Pengenalan kepada Spring Data Elasticsearch

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan meneroka asas-asas Spring Data Elasticsearch secara berfokus pada kod dan praktikal.

Kami akan menunjukkan cara mengindeks, mencari, dan membuat pertanyaan Elasticsearch dalam aplikasi Spring menggunakan Spring Data Elasticsearch. Spring Data Elasticseach adalah modul Spring yang menerapkan Spring Data sehingga menawarkan cara untuk berinteraksi dengan enjin carian sumber terbuka, Lucene yang popular.

Walaupun Elasticsearch dapat berfungsi tanpa skema yang jelas, ini adalah kebiasaan untuk merancang dan membuat pemetaan yang menentukan jenis data yang diharapkan dalam bidang tertentu . Apabila dokumen diindeks, bidangnya diproses mengikut jenisnya. Sebagai contoh, medan teks akan diberi token dan disaring mengikut peraturan pemetaan. Kita juga boleh membuat penapis dan tokenizer kita sendiri.

Demi kesederhanaan, kami akan menggunakan gambar pelabuhan untuk contoh Elasticsearch kami, walaupun ada contoh Elasticsearch yang mendengar di port 9200 .

Kita mulakan dengan membuka contoh Elasticsearch:

docker run -d --name es762 -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.6.2

2. Data Spring

Spring Data membantu mengelakkan kod plat boiler. Sebagai contoh, jika kita menentukan antara muka repositori yang memperluas antara muka ElasticsearchRepository yang disediakan oleh Spring Data Elasticsearch , operasi CRUD untuk kelas dokumen yang sesuai akan disediakan secara lalai.

Selain itu, hanya dengan menyatakan kaedah dengan nama dalam format yang telah ditentukan, pelaksanaan kaedah dihasilkan untuk kita - tidak perlu menulis pelaksanaan antara muka repositori.

Panduan Baeldung mengenai Spring Data memberikan perkara penting untuk memulakan topik ini.

2.1. Ketergantungan Maven

Spring Data Elasticsearch menyediakan API Java untuk mesin pencari. Untuk menggunakannya, kita perlu menambahkan kebergantungan baru ke pom.xml :

 org.springframework.data spring-data-elasticsearch 4.0.0.RELEASE 

2.2. Mendefinisikan Antaramuka Repositori

Untuk menentukan repositori baru, kami memperluas salah satu antara muka repositori yang disediakan, menggantikan jenis generik dengan jenis dokumen sebenar dan jenis utama kami.

Penting untuk diperhatikan bahawa ElasticsearchRepository meluas dari PagingAndSortingRepository. Ini membolehkan sokongan terpadu untuk penomboran dan penyusun.

Dalam contoh kami, kami akan menggunakan ciri halaman dalam kaedah carian tersuai kami:

public interface ArticleRepository extends ElasticsearchRepository { Page findByAuthorsName(String name, Pageable pageable); @Query("{\"bool\": {\"must\": [{\"match\": {\"authors.name\": \"?0\"}}]}}") Page findByAuthorsNameUsingCustomQuery(String name, Pageable pageable); }

Dengan kaedah findByAuthorsName , proksi repositori akan membuat pelaksanaan berdasarkan nama kaedah. Algoritma resolusi akan menentukan bahawa ia perlu mengakses harta benda penulis dan kemudian mencari harta nama setiap item.

Kaedah kedua, findByAuthorsNameUsingCustomQuery , menggunakan pertanyaan boolean Elasticsearch tersuai, yang ditentukan menggunakan anotasi @Query , yang memerlukan pemadanan ketat antara nama pengarang dan argumen nama yang disediakan .

2.3. Konfigurasi Java

Semasa mengkonfigurasi Elasticsearch dalam aplikasi Java kita, kita perlu menentukan bagaimana kita menyambung ke instance Elasticsearch. Untuk itu, kami menggunakan RestHighLevelClient yang ditawarkan oleh pergantungan Elasticsearch:

@Configuration @EnableElasticsearchRepositories(basePackages = "com.baeldung.spring.data.es.repository") @ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" }) public class Config { @Bean public RestHighLevelClient client() { ClientConfiguration clientConfiguration = ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); return RestClients.create(clientConfiguration).rest(); } @Bean public ElasticsearchOperations elasticsearchTemplate() { return new ElasticsearchRestTemplate(client()); } }

Kami menggunakan anotasi gaya musim bunga standard. @EnableElasticsearchRepositories akan membuat Spring Data Elasticsearch mengimbas pakej yang disediakan untuk repositori Spring Data.

Untuk berkomunikasi dengan pelayan Elasticsearch, kami menggunakan RestHighLevelClient yang ringkas . Walaupun Elasticsearch menyediakan pelbagai jenis klien, menggunakan RestHighLevelClient adalah cara yang baik untuk membuktikan komunikasi di masa depan dengan pelayan.

Akhirnya, kami menyediakan kacang ElasticsearchOperations untuk menjalankan operasi di pelayan kami. Dalam kes ini, kami mewujudkan ElasticsearchRestTemplate .

3. Pemetaan

Pemetaan digunakan untuk menentukan skema untuk dokumen kami. Dengan menentukan skema pada dokumen kami, kami melindunginya dari hasil yang tidak diingini seperti pemetaan ke jenis yang tidak kami inginkan.

Entiti kami adalah dokumen ringkas bernama Artikel di mana id adalah jenis String . Kami juga menyatakan bahawa dokumen tersebut mesti disimpan dalam indeks bernama blog dalam jenis artikel .

@Document(indexName = "blog", type = "article") public class Article { @Id private String id; private String title; @Field(type = FieldType.Nested, includeInParent = true) private List authors; // standard getters and setters }

Indeks boleh mempunyai beberapa jenis. Kita boleh menggunakan ciri tersebut untuk melaksanakan hierarki.

Yang penulis bidang ditandakan sebagai FieldType.Nested . Ini membolehkan kita menentukan kelas Pengarang secara berasingan, tetapi mempunyai contoh individu pengarang yang disertakan dalam dokumen Artikel ketika diindeks di Elasticsearch.

4. Pengindeksan Dokumen

Spring Data Elasticsearch secara amnya membuat indeks secara automatik berdasarkan entiti dalam projek tersebut. Namun, kami juga dapat membuat indeks secara terprogram melalui templat pelanggan:

elasticsearchTemplate.indexOps(Article.class).create();

Kemudian, kita dapat menambahkan dokumen ke indeks:

Article article = new Article("Spring Data Elasticsearch"); article.setAuthors(asList(new Author("John Smith"), new Author("John Doe"))); articleRepository.save(article);

5. Membuat pertanyaan

5.1. Kaedah Berdasarkan Nama Kaedah

Apabila kita menggunakan pertanyaan berdasarkan nama kaedah, kita menulis kaedah yang menentukan pertanyaan yang ingin kita laksanakan. Semasa penyediaan, Spring Data akan menguraikan tandatangan kaedah dan membuat pertanyaan dengan sewajarnya:

String nameToFind = "John Smith"; Page articleByAuthorName = articleRepository.findByAuthorsName(nameToFind, PageRequest.of(0, 10));

Dengan memanggil findByAuthorsName dengan objek PageRequest , kami memperoleh halaman hasil pertama (penomboran halaman berdasarkan sifar), dengan halaman tersebut memuat paling banyak 10 artikel. Objek halaman juga memberikan jumlah klik untuk pertanyaan bersama dengan maklumat penomboran lain yang berguna.

5.2. Pertanyaan Tersuai

There are a couple of ways to define custom queries for Spring Data Elasticsearch repositories. One way is to use the @Query annotation, as demonstrated in section 2.2.

Another option is to use the query builder to create our custom query.

Having to search for articles that have the word “data” in the title, we could just create a NativeSearchQueryBuilder with a Filter on the title:

Query searchQuery = new NativeSearchQueryBuilder() .withFilter(regexpQuery("title", ".*data.*")) .build(); SearchHits articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog");

6. Updating and Deleting

In order to update a document, we first must retrieve it:

String articleTitle = "Spring Data Elasticsearch"; Query searchQuery = new NativeSearchQueryBuilder() .withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")) .build(); SearchHits articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"); Article article = articles.getSearchHit(0).getContent();

Then, we can make changes to the document just by editing the content of the object using its assessors:

article.setTitle("Getting started with Search Engines"); articleRepository.save(article);

As for deleting, there are several options. We can retrieve the document and delete it using the delete method:

articleRepository.delete(article);

Kami juga boleh menghapusnya dengan id apabila diketahui:

articleRepository.deleteById("article_id");

Anda juga boleh membuat pertanyaan deleteBy khas dan menggunakan ciri penghapusan pukal yang ditawarkan oleh Elasticsearch:

articleRepository.deleteByTitle("title");

7. Kesimpulannya

Dalam tutorial ini, kami meneroka cara menghubungkan dan memanfaatkan Spring Data Elasticsearch. Kami membincangkan bagaimana kami boleh membuat pertanyaan, mengemas kini dan menghapus dokumen. Selain itu, kami juga membincangkan cara membuat pertanyaan khusus dan tidak sesuai dengan apa yang ditawarkan oleh Spring Data Elasticsearch.

Seperti biasa, kod sumber yang digunakan sepanjang tutorial ini boleh didapati di GitHub.