Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Next Level Elasticsearch Integration with Sprin...
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Peter-Josef Meisch
October 15, 2020
Programming
1
130
Next Level Elasticsearch Integration with Spring Data Elasticsearch
The slides for my session at ElasticON Global on October 14th and 15th 2020
Peter-Josef Meisch
October 15, 2020
Tweet
Share
Other Decks in Programming
See All in Programming
AI によるインシデント初動調査の自動化を行う AI インシデントコマンダーを作った話
azukiazusa1
1
740
CSC307 Lecture 05
javiergs
PRO
0
500
360° Signals in Angular: Signal Forms with SignalStore & Resources @ngLondon 01/2026
manfredsteyer
PRO
0
130
疑似コードによるプロンプト記述、どのくらい正確に実行される?
kokuyouwind
0
390
Oxlintはいいぞ
yug1224
5
1.3k
[KNOTS 2026登壇資料]AIで拡張‧交差する プロダクト開発のプロセス および携わるメンバーの役割
hisatake
0
290
16年目のピクシブ百科事典を支える最新の技術基盤 / The Modern Tech Stack Powering Pixiv Encyclopedia in its 16th Year
ahuglajbclajep
5
1k
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
130
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
180
Automatic Grammar Agreementと Markdown Extended Attributes について
kishikawakatsumi
0
200
CSC307 Lecture 06
javiergs
PRO
0
690
CSC307 Lecture 09
javiergs
PRO
1
840
Featured
See All Featured
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
150
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
9.9k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
200
Breaking role norms: Why Content Design is so much more than writing copy - Taylor Woolridge
uxyall
0
170
Producing Creativity
orderedlist
PRO
348
40k
The SEO identity crisis: Don't let AI make you average
varn
0
290
Discover your Explorer Soul
emna__ayadi
2
1.1k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
110
Marketing to machines
jonoalderson
1
4.6k
Building a Scalable Design System with Sketch
lauravandoore
463
34k
Transcript
1 ElasticON Global Peter-Josef Meisch Spring Data Elasticsearch Project Lead
2 Nothing will stop you being creative more effectively as
the fear of making a mistake. John Cleese
3 Next Level Elasticsearch Integration with Spring Data Elasticsearch
What is Spring Data Elasticsearch?
“Spring Data’s mission is to provide a familiar and consistent,
Spring-based programming model for data access while still retaining the special traits of the underlying data store.”
Configure the connection to Elasticsearch
Configure the connection to Elasticsearch @Configuration public class RestClientConfig extends
AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); return RestClients.create(clientConfiguration).rest(); } }
Configure the connection to Elasticsearch @Configuration public class RestClientConfig extends
AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .withProxy("localhost:8080") .build(); return RestClients.create(clientConfiguration).rest(); } }
Configure the connection to Elasticsearch @Configuration public class RestClientConfig extends
AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .usingSsl() .build(); return RestClients.create(clientConfiguration).rest(); } }
Configure the connection to Elasticsearch @Configuration public class RestClientConfig extends
AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .withBasicAuth("myuser", "mypassword") .build(); return RestClients.create(clientConfiguration).rest(); } }
Configure the connection to Elasticsearch @Configuration public class RestClientConfig extends
AbstractElasticsearchConfiguration { @Override @Bean public RestHighLevelClient elasticsearchClient() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .withPathPrefix("customer1") .build(); return RestClients.create(clientConfiguration).rest(); } }
Configure the connection to Elasticsearch Supplier<HttpHeaders> currentTimeHeaders = () ->
{ HttpHeaders headers = new HttpHeaders(); headers.add("currentTime", LocalDateTime.now() .format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); return headers; }; ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .withHeaders(currentTimeHeaders) .build();
Entity definition
Entity definition public class Person { @Id private String id;
private String lastName; private String firstName; private LocalDate birthDate; }
Entity definition @Document(indexName = "person") public class Person { @Id
private String id; private String lastName; private String firstName; private LocalDate birthDate; }
Entity definition @Document(indexName = "person") public class Person { @Id
private String id; @Field(type = FieldType.Text) private String lastName; @Field(type = FieldType.Text) private String firstName; private LocalDate birthDate; }
Entity definition @Document(indexName = "person") public class Person { @Id
private String id; @Field(type = FieldType.Text) private String lastName; @Field(type = FieldType.Text) private String firstName; @Field(type = FieldType.Date, format = DateFormat.basic_date) private LocalDate birthDate; }
ElasticsearchOperations
IndexOperations • index creation and deletion • index settings •
index mappings • index templates • alias management • refresh operation
IndexOperations private ElasticsearchOperations operations ; // injected by Spring IndexOperations
indexOps = operations.indexOps(Person.class); indexOps.create(); indexOps.putMapping(); PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("template-name", "log-*") .withSettings(settings) .withMappings(mapping) .withAliasActions(aliasActions) .build(); indexOps.putTemplate(putTemplateRequest);
IndexOperations private ElasticsearchOperations operations; // injected by Spring IndexOperations indexOps
= operations.indexOps(Person.class) ; indexOps.create(); indexOps.putMapping(); PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("template-name", "log-*") .withSettings(settings) .withMappings(mapping) .withAliasActions(aliasActions) .build(); indexOps.putTemplate(putTemplateRequest);
IndexOperations private ElasticsearchOperations operations; // injected by Spring IndexOperations indexOps
= operations.indexOps(Person.class); indexOps.create(); indexOps.putMapping(); PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("template-name", "log-*") .withSettings(settings) .withMappings(mapping) .withAliasActions(aliasActions) .build(); indexOps.putTemplate(putTemplateRequest);
IndexOperations private ElasticsearchOperations operations; // injected by Spring IndexOperations indexOps
= operations.indexOps(Person.class); indexOps.create(); indexOps.putMapping(); PutTemplateRequest putTemplateRequest = PutTemplateRequest.builder("template-name", "log-*") .withSettings(settings) .withMappings(mapping) .withAliasActions(aliasActions) .build(); indexOps.putTemplate(putTemplateRequest) ;
DocumentOperations • save • get • delete • exists •
update
SearchOperations • count • search Query based operations
NativeSearchQuery import static org.elasticsearch.index.query.QueryBuilders.*; import static org.elasticsearch.search.aggregations.AggregationBuilders.*; Query query =
new NativeSearchQueryBuilder() .addAggregation( terms("lastNames").field("lastName").size(10) ) .withQuery( matchQuery("firstName", firstName) ) .build(); SearchHits<Person> searchHits = operations.search(query, Person.class);
StringQuery Query query = new StringQuery( "{" + " \"bool\":
{" + " \"must\": [" + " {" + " \"match\": {" + " \"lastName\": \"Smith\"" + " }" + " }" + " ]" + " }" + "}"); SearchHits<Person> searchHits = operations.search(query, Person.class);
CriteriaQuery Criteria criteria = new Criteria("lastName").is("Smith") .and("firstName").is("James"); Query query =
new CriteriaQuery(criteria); SearchHits<Person> searchHits = operations.search(query, Person.class);
Return types
SearchHit<T • id • index name • the entity of
type T • score • sort values • highlight fields • inner hits
SearchHits<T • number of total hits • total hits relation
(eq, gte) • list of SearchHit<T> objects • max score • aggregations
ElasticsearchRepository
Repository interface PersonRepository extends ElasticsearchRepository< Person, String > { }
// ElasticsearchRepository // +PagingAndSortingRepository // + CrudRepository // + Repository
Repository count() delete(T) deleteAll() deleteAll(Iterable<? extends T) deleteById(ID) existsById(ID) findAll()
findAll(Pageable) findAll(Sort) findAllById(Iterable<ID>) findById(ID) save(T) saveAll(Iterable<T>) searchSimilar(T entity, String[] fields, Pageable pageable)
Repository methods interface PersonRepository extends ElasticsearchRepository< Person, String > {
List<Person> searchByFirstName(String name); List<Person> findByFirstNameOrderByLastNameAsc(String name); List<Person> queryByBirthDateBefore(LocalDate date); }
Repository methods interface PersonRepository extends ElasticsearchRepository<Person, String> { @Query(value =
"{\"fuzzy\":{\"lastName\":\"?0\"}}") List<Person> findByLastNameFuzzy(String lastName); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
List<Person> searchByFirstName(String name); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
Stream<Person> searchByFirstName(String name); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
List<SearchHit<Person>> searchByFirstName(String name); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
Stream<SearchHit<Person>> searchByFirstName(String name); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
SearchHits<Person> searchByFirstName(String name); }
Repository method return types interface PersonRepository extends ElasticsearchRepository<Person, String> {
SearchPage<Person> searchByFirstName(String name, Pageable page); }
Repository usage @RestController @RequestMapping(”/persons”) public class PersonController { private PersonRepository
repository; public PersonController(PersonRepository repository) { this.repository = repository; } @GetMapping(”/firstName/{name}”) List<Person> byFirstName( @PathVariable(”name”) String name) { return repository.searchByFirstName(name) ; } }
Repository method with highlight definition interface PersonRepository extends ElasticsearchRepository<Person, String>
{ @Highlight(fields = { @HighlightField(name = "firstName") }) SearchHits<Person> searchByFirstName(String name); } repository.searchByFirstName(”James”) .forEach(searchHit -> { List<String> highlights = searchHit.getHighlightField("firstName"); // ... });
What else?
Lifecycle events @Component public class PersonBeforeConvertCallback implements BeforeConvertCallback<Person> { @Override
public Person onBeforeConvert(Person person, IndexCoordinates indexCoordinates) { if (person.getId() == null) { person.setId(UUID.randomUUID().toString()); } return person; } }
Auditable Entity @Document(indexName = "person") public class Person implements Persistable<String>
{ @Id private String id; @CreatedDate @Field(type = FieldType.Date, format = DateFormat.basic_date_time) private Instant created; @CreatedBy private String createdBy; @Override public boolean isNew() { return id == null || (createdBy == null && created == null); } }
We need contributors! Spring Data Elasticsearch is a community-driven project
49 Thank You! https://spring.io/projects/spring-data-elasticsearch https://github.com/spring-projects/spring-data-elasticsearch @sothawo
[email protected]