Panduan untuk Elasticsearch di Jawa

1. Gambaran keseluruhan

Dalam artikel ini, kita akan menyelami beberapa konsep utama yang berkaitan dengan enjin carian teks penuh, dengan fokus khusus pada Elasticsearch.

Oleh kerana ini adalah artikel berorientasi Java, kami tidak akan memberikan tutorial langkah demi langkah terperinci mengenai cara menyiapkan Elasticsearch dan menunjukkan bagaimana ia berfungsi di bawah tenda. Sebagai gantinya, kita akan menargetkan klien Java, dan bagaimana menggunakan ciri utama seperti indeks , hapus , dapatkan dan cari .

2. Persediaan

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

Secara lalai, Elasticsearch mendengar di port 9200 untuk pertanyaan HTTP yang akan datang. Kami dapat mengesahkan bahawa ia berjaya dilancarkan dengan membuka // localhost: 9200 / URL di penyemak imbas kegemaran anda:

{ "name" : "M4ojISw", "cluster_name" : "docker-cluster", "cluster_uuid" : "CNnjvDZzRqeVP-B04D3CmA", "version" : { "number" : "7.6.2", "build_flavor" : "default", "build_type" : "docker", "build_hash" : "2f4c224", "build_date" : "2020-03-18T23:22:18.622755Z", "build_snapshot" : false, "lucene_version" : "8.4.0", "minimum_wire_compatibility_version" : "6.8.0", "minimum_index_compatibility_version" : "6.8.0-beta1" }, "tagline" : "You Know, for Search" }

3. Konfigurasi Maven

Sekarang kami mempunyai kluster Elasticsearch asas kami dan berjalan, mari langsung ke klien Java. Pertama sekali, kita perlu menyatakan pergantungan Maven berikut dalam fail pom.xml kami :

 org.elasticsearch elasticsearch 7.6.2 

Anda sentiasa boleh memeriksa versi terkini yang dihoskan oleh Maven Central dengan pautan yang disediakan sebelumnya.

4. API Java

Sebelum melangkah langsung ke cara menggunakan ciri Java API utama, kita perlu memulakan RestHighLevelClient :

ClientConfiguration clientConfiguration = ClientConfiguration.builder().connectedTo("localhost:9200").build(); RestHighLevelClient client = RestClients.create(clientConfiguration).rest();

4.1. Dokumen Pengindeksan

Fungsi index () memungkinkan untuk menyimpan dokumen JSON sewenang-wenang dan membuatnya dapat dicari:

@Test public void givenJsonString_whenJavaObject_thenIndexDocument() { String jsonObject = "{\"age\":10,\"dateOfBirth\":1471466076564," +"\"fullName\":\"John Doe\"}"; IndexRequest request = new IndexRequest("people"); request.source(jsonObject, XContentType.JSON); IndexResponse response = client.index(request, RequestOptions.DEFAULT); String index = response.getIndex(); long version = response.getVersion(); assertEquals(Result.CREATED, response.getResult()); assertEquals(1, version); assertEquals("people", index); }

Perhatikan bahawa ada kemungkinan menggunakan perpustakaan JSON Java untuk membuat dan memproses dokumen anda. Sekiranya anda tidak biasa dengan semua ini, anda boleh menggunakan pembantu Elasticsearch untuk menghasilkan dokumen JSON anda sendiri :

XContentBuilder builder = XContentFactory.jsonBuilder() .startObject() .field("fullName", "Test") .field("dateOfBirth", new Date()) .field("age", "10") .endObject(); IndexRequest indexRequest = new IndexRequest("people"); indexRequest.source(builder); IndexResponse response = client.index(indexRequest, RequestOptions.DEFAULT); assertEquals(Result.CREATED, response.getResult());

4.2. Meminta Dokumen Terindeks

Sekarang kita mempunyai dokumen JSON yang dapat dicari yang diindeks, kita dapat meneruskan dan mencari menggunakan kaedah carian () :

SearchRequest searchRequest = new SearchRequest(); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT); SearchHit[] searchHits = response.getHits().getHits(); List results = Arrays.stream(searchHits) .map(hit -> JSON.parseObject(hit.getSourceAsString(), Person.class)) .collect(Collectors.toList());

Hasil yang dikembalikan dengan kaedah carian () disebut Hits , setiap Hit merujuk kepada dokumen JSON yang sesuai dengan permintaan carian.

Dalam kes ini, senarai hasil mengandungi semua data yang tersimpan dalam kluster. Perhatikan bahawa dalam contoh ini kita menggunakan perpustakaan FastJson untuk menukar JSON Strings ke objek Java.

Kami dapat meningkatkan permintaan dengan menambahkan parameter tambahan untuk menyesuaikan permintaan menggunakan kaedah QueryBuilders :

SearchSourceBuilder builder = new SearchSourceBuilder() .postFilter(QueryBuilders.rangeQuery("age").from(5).to(15)); SearchRequest searchRequest = new SearchRequest(); searchRequest.searchType(SearchType.DFS_QUERY_THEN_FETCH); searchRequest.source(builder); SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

4.3. Mengambil dan Memadam Dokumen

Kaedah get () dan delete () memungkinkan untuk mendapatkan atau menghapus dokumen JSON dari kluster menggunakan idnya:

GetRequest getRequest = new GetRequest("people"); getRequest.id(id); GetResponse getResponse = client.get(getRequest, RequestOptions.DEFAULT); // process fields DeleteRequest deleteRequest = new DeleteRequest("people"); deleteRequest.id(id); DeleteResponse deleteResponse = client.delete(deleteRequest, RequestOptions.DEFAULT);

Sintaksnya cukup mudah, anda hanya perlu menentukan indeks di samping id objek.

5. Contoh QueryBuilders

The QueryBuilders kelas menyediakan pelbagai kaedah statik digunakan sebagai matchers dinamik untuk mencari entri tertentu dalam kelompok. Sambil menggunakan kaedah pencarian () untuk mencari dokumen JSON tertentu dalam kluster, kami dapat menggunakan pembangun pertanyaan untuk menyesuaikan hasil pencarian.

Berikut adalah senarai kegunaan API QueryBuilders yang paling biasa .

Kaedah matchAllQuery () mengembalikan objek QueryBuilder yang sesuai dengan semua dokumen dalam kluster:

QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

The rangeQuery () perlawanan dokumen di mana nilai medan adalah dalam julat yang tertentu:

QueryBuilder matchDocumentsWithinRange = QueryBuilders .rangeQuery("price").from(15).to(100)

Menyediakan nama medan - misalnya nama penuh , dan nilai yang sesuai - contohnya John Doe , kaedah matchQuery () memadankan semua dokumen dengan nilai bidang yang tepat ini:

QueryBuilder matchSpecificFieldQuery= QueryBuilders .matchQuery("fullName", "John Doe");

Kita juga boleh menggunakan kaedah multiMatchQuery () untuk membina versi padanan pertanyaan padanan:

QueryBuilder matchSpecificFieldQuery= QueryBuilders.matchQuery( "Text I am looking for", "field_1", "field_2^3", "*_field_wildcard");

Kita dapat menggunakan simbol karet (^) untuk meningkatkan bidang tertentu .

Dalam contoh kami, bidang_2 mempunyai nilai dorongan yang ditetapkan menjadi tiga, menjadikannya lebih penting daripada bidang lain. Perhatikan bahawa mungkin menggunakan pertanyaan wildcard dan regex, tetapi berdasarkan prestasi, berhati-hatilah terhadap penggunaan memori dan kelewatan masa tindak balas ketika berhadapan dengan wildcard, kerana sesuatu seperti * _apel boleh menyebabkan kesan besar terhadap prestasi.

The coefficient of importance is used to order the result set of hits returned after executing the search() method.

If you are more familiar with the Lucene queries syntax, you can use the simpleQueryStringQuery() method to customize search queries:

QueryBuilder simpleStringQuery = QueryBuilders .simpleQueryStringQuery("+John -Doe OR Janette");

As you can probably guess, we can use the Lucene's Query Parser syntax to build simple, yet powerful queries. Here're some basic operators that can be used alongside the AND/OR/NOT operators to build search queries:

  • The required operator (+): requires that a specific piece of text exists somewhere in fields of a document.
  • Operator larangan ( - ): tidak termasuk semua dokumen yang mengandungi kata kunci yang dinyatakan selepas simbol ( - ).

6. Kesimpulannya

Dalam artikel ringkas ini, kami telah melihat bagaimana menggunakan Java API ElasticSearch untuk melakukan beberapa ciri umum yang berkaitan dengan mesin carian teks penuh.

Anda boleh melihat contoh yang diberikan dalam artikel ini dalam projek GitHub.