Spring Elasticsearch Operations
Elasticsearch Operations
Spring Data Elasticsearch uses two interfaces to define the operations that can be called against an Elasticsearch index. These are ElasticsearchOperations and ReactiveElasticsearchOperations. Whereas the first is used with the classic synchronous implementations, the second one uses reactive infrastructure.The default implementations of the interfaces offer:
Read/Write mapping support for domain types.
A rich query and criteria api.
Resource management and Exception translation.
ElasticsearchTemplate
The ElasticsearchTemplate is an implementation of the ElasticsearchOperations interface using the Transport Client.@Configuration
public class TransportClientConfig extends ElasticsearchConfigurationSupport {
@Bean
public Client elasticsearchClient() throws UnknownHostException {
Settings settings = Settings.builder().put("cluster.name", "elasticsearch").build();
TransportClient client = new PreBuiltTransportClient(settings);
client.addTransportAddress(new TransportAddress(InetAddress.getByName("127.0.0.1"), 9300));
return client;
}
@Bean(name = {"elasticsearchOperations", "elasticsearchTemplate"})
public ElasticsearchTemplate elasticsearchTemplate() throws UnknownHostException {
return new ElasticsearchTemplate(elasticsearchClient(), entityMapper());
}
// use the ElasticsearchEntityMapper
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
new DefaultConversionService());
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
}
ElasticsearchRestTemplate
The ElasticsearchRestTemplate is an implementation of the ElasticsearchOperations interface using the High Level REST Client.@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
@Override
public RestHighLevelClient elasticsearchClient() {
return RestClients.create(ClientConfiguration.localhost()).rest();
}
// no special bean creation needed
// use the ElasticsearchEntityMapper
@Bean
@Override
public EntityMapper entityMapper() {
ElasticsearchEntityMapper entityMapper = new ElasticsearchEntityMapper(elasticsearchMappingContext(),
new DefaultConversionService());
entityMapper.setConversions(elasticsearchCustomConversions());
return entityMapper;
}
}
Both ElasticsearchTemplate and ElasticsearchRestTemplate implement the ElasticsearchOperations interface, the code to use them is not different. The example shows how to use an injected ElasticsearchOperations instance in a Spring REST controller. The decision, if this is using the TransportClient or the RestClient is made by providing the corresponding Bean with one of the configurations shown above.
@RestController
@RequestMapping("/")
public class TestController {
private ElasticsearchOperations elasticsearchOperations;
public TestController(ElasticsearchOperations elasticsearchOperations) {
this.elasticsearchOperations = elasticsearchOperations;
}
@PostMapping("/person")
public String save(@RequestBody Person person) {
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(person.getId().toString())
.withObject(person)
.build();
String documentId = elasticsearchOperations.index(indexQuery);
return documentId;
}
@GetMapping("/person/{id}")
public Person findById(@PathVariable("id") Long id) {
Person person = elasticsearchOperations
.queryForObject(GetQuery.getById(id.toString()), Person.class);
return person;
}
}
Reactive Template Configuration
The easiest way of setting up the ReactiveElasticsearchTemplate is via AbstractReactiveElasticsearchConfiguration providing dedicated configuration method hooks for base package, the initial entity set etc.ReactiveElasticsearchOperations is the gateway to executing high level commands against an Elasticsearch cluster using the ReactiveElasticsearchClient.
The ReactiveElasticsearchTemplate is the default implementation of ReactiveElasticsearchOperations.
To get started the ReactiveElasticsearchTemplate needs to know about the actual client to work with.
@Configuration
public class Config extends AbstractReactiveElasticsearchConfiguration {
@Bean
@Override
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
// ...
}
}
Configure the ReactiveElasticsearchTemplate
@Configurationpublic class Config {
@Bean
public ReactiveElasticsearchClient reactiveElasticsearchClient() {
// ...
}
@Bean
public ElasticsearchConverter elasticsearchConverter() {
return new MappingElasticsearchConverter(elasticsearchMappingContext());
}
@Bean
public SimpleElasticsearchMappingContext elasticsearchMappingContext() {
return new SimpleElasticsearchMappingContext();
}
@Bean
public ReactiveElasticsearchOperations reactiveElasticsearchOperations() {
return new ReactiveElasticsearchTemplate(reactiveElasticsearchClient(), elasticsearchConverter());
}
}
Use the ReactiveElasticsearchTemplate
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))
.doOnNext(System.out::println)
.flatMap(person -> template.findById(person.id, Person.class))
.doOnNext(System.out::println)
.flatMap(person -> template.delete(person))
.doOnNext(System.out::println)
.flatMap(id -> template.count(Person.class))
.doOnNext(System.out::println)
.subscribe();
Comments
Post a Comment