Fix generics in ElasticsearchEntityMapper. Extract methods. Move enum conversion handling to simple type handling for symmetric implementation. Swap comparison of nullable types to avoid potential null dereference.
Rename ElasticsearchDefaultTypeMapper to DefaultElasticsearchTypeMapper. Move MapTypeAliasAccessor to DefaultElasticsearchTypeMapper.
Introduce SearchResultMapperAdapter to avoid empty method implementations in anonymous classes. Javadoc, reference docs, formatting.
Original Pull Request: #237
The root cause of the deletion problem was the doScroll which did not apply the given query and therefor returned all entries from the index.
The doScroll implementation has been fixed to apply the query and multiple unit tests have been added to ensure that the delete methods delete the desired documents only and leave the rest untouched.
Also added unit tests for the scrolling to test it against real queries (not only matchAll).
Original pull request: #240
The getMapping methods in the ElasticsearchRestTemplate now behave like the methods in the ElasticsearchTemplate and return the mapping for the specified index and type.
Original pull request: #239
Reactive Elasticsearch repository support builds on the core repository support utilizing
operations provided via ReactiveElasticsearchOperations executed by a ReactiveElasticsearchClient.
Spring Data Elasticsearchs reactive repository support uses Project Reactor as its reactive
composition library of choice.
There are 3 main interfaces to be used:
* ReactiveRepository
* ReactiveCrudRepository
* ReactiveSortingRepository
For Java configuration, use the @EnableReactiveElasticsearchRepositories annotation.
The following listing shows how to use Java configuration for a repository:
@Configuration
@EnableReactiveElasticsearchRepositories
public class Config extends AbstractReactiveElasticsearchConfiguration {
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
return ReactiveRestClients.create(ClientConfiguration.localhost());
}
}
Using a repository that extends ReactiveSortingRepository makes all CRUD operations available
as well as methods for sorted access to the entities. Working with the repository instance is a matter of dependency
injecting it into a client.
The repository itself allows defining additional methods backed by the inferred proxy.
public interface ReactivePersonRepository extends ReactiveSortingRepository<Person, String> {
Flux<Person> findByFirstname(String firstname);
Flux<Person> findByFirstname(Publisher<String> firstname);
Flux<Person> findByFirstnameOrderByLastname(String firstname);
Flux<Person> findByFirstname(String firstname, Sort sort);
Flux<Person> findByFirstname(String firstname, Pageable page);
Mono<Person> findByFirstnameAndLastname(String firstname, String lastname);
Mono<Person> findFirstByLastname(String lastname);
@Query("{ \"bool\" : { \"must\" : { \"term\" : { \"lastname\" : \"?0\" } } } }")
Flux<Person> findByLastname(String lastname);
Mono<Long> countByFirstname(String firstname)
Mono<Boolean> existsByFirstname(String firstname)
Mono<Long> deleteByFirstname(String firstname)
}
Original Pull Request: #235
Wrap Scroll execution with usingWhen and run cleanup through usingWhen callback to clean up scrolls state on success/on error/on cancellation.
Extract isEmpty(SearchHits) check into own method. Improve synchronization in ScrollState to prevent concurrent modification exceptions during read.
Original Pull Request: #231
The ReactiveElasticsearchClient now support scrolling through large result sets issuing subsequent _search/scroll requests while emitting data on the outbound channel. Resources bound via their scrollId get freed on completion of the flux.
Original Pull Request: #231
Update documentation to cover newly added configuration options for the ReactiveElasticsearchClient.
Make sure to apply postFilter correctly and set a default limit for unpaged search requests.
Also fix some code format issues.
We now log HTTP requests and responses with the org.springframework.data.elasticsearch.client.WIRE logger for both, the HighLevelRestClient and our reactive client and associate a logging Id for improved traceability.
Configuration of connection/socket timeouts is now available via the ClientConfiguration.
Along the lines we also aligned entity handling to EntityOperations already common in other modules. EntityOperations centralizes how aspects of entities (versioning, retrieval of index name/index type) are handled.
Original Pull Request: #229
ReactiveElasticsearchOperations is the gateway to executing high level commands against an Elasticsearch cluster using the ReactiveElasticsearchClient.
The ReactiveElasticsearchTemplate is the default implementation of ReactiveElasticsearchOperations and offers the following set of features.
* Read/Write mapping support for domain types.
* A rich query and criteria api.
* Resource management and Exception translation.
To get started the ReactiveElasticsearchTemplate needs to know about the actual client to work with.
The easiest way of setting up the ReactiveElasticsearchTemplate is via AbstractReactiveElasticsearchConfiguration providing
dedicated configuration method hooks for base package, the initial entity set etc.
@Configuration
public class Config extends AbstractReactiveElasticsearchConfiguration {
@Bean
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
// ...
}
}
NOTE: If applicable set default HttpHeaders via the ClientConfiguration of the ReactiveElasticsearchClient.
TIP: If needed the ReactiveElasticsearchTemplate can be configured with default RefreshPolicy and IndicesOptions that get applied to the related requests by overriding the defaults of refreshPolicy() and indicesOptions().
The ReactiveElasticsearchTemplate lets you save, find and delete your domain objects and map those objects to documents stored in Elasticsearch.
@Document(indexName = "marvel", type = "characters")
public class Person {
private @Id String id;
private String name;
private int age;
// Getter/Setter omitted...
}
template.save(new Person("Bruce Banner", 42)) // save a new document
.doOnNext(System.out::println)
.flatMap(person -> template.findById(person.id, Person.class)) // then go find it
.doOnNext(System.out::println)
.flatMap(person -> template.delete(person)) // just to remove remove it again
.doOnNext(System.out::println)
.flatMap(id -> template.count(Person.class)) // so we've got nothing at the end
.doOnNext(System.out::println)
.subscribe(); // yeah :)
The above outputs the following sequence on the console.
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> Person(id=QjWCWWcBXiLAnp77ksfR, name=Bruce Banner, age=42)
> QjWCWWcBXiLAnp77ksfR
> 0
Original Pull Request: #229
Convert spaces to tabs for pom.xml. Switch reactive dependencies to optional. Remove unused commonscollections property. Use managed versions for reactor and Spring dependencies.
Introduce WebClientProvider to avoid reinstantiation of WebClient instances. Introduce ClientConfiguration to encapsulate common Elasticsearch client configuration properties. Split ElasticsearchClients into RestClients and ReactiveRestClients to avoid mandatory dependency on WebFlux/Project Reactor. Adapt tests and code referring to WebClient creation.
Extract response body as byte array instead of Flux of DataBuffer to avoid chunking and to parse an entire response.
Encapsulate hostAndPort string used across configuration/HostProvider with InetSocketAddress. Add parser for InetSocketAddress.
Original Pull Request: #226