1. 概要

この記事では、Elasticsearchに特に焦点を当てて、全文検索エンジンに関連するいくつかの重要な概念について詳しく説明します。

これはJava指向の記事であるため、Elasticsearchのセットアップ方法と、内部でどのように機能するかを示す詳細なステップバイステップのチュートリアルは提供しません。 代わりに、Javaクライアントを対象とし、 index delete get searchなどの主な機能の使用方法を説明します。

2. 設定

簡単にするために、ElasticsearchインスタンスにはDockerイメージを使用しますが、ポート9200でリッスンしているElasticsearchインスタンスはを使用します。

まず、Elasticsearchインスタンスを起動します。

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

デフォルトでは、Elasticsearchは9200ポートで今後のHTTPクエリをリッスンします。 お気に入りのブラウザでhttp:// localhost:9200 / URLを開くと、正常に起動されたことを確認できます。

{
  "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. Maven構成

基本的なElasticsearchクラスターが稼働しているので、Javaクライアントに直接ジャンプしましょう。 まず、pom.xmlファイルで次のMaven依存関係を宣言する必要があります。

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>7.6.2</version>
</dependency>

以前に提供されたリンクを使用して、MavenCentralによってホストされている最新バージョンをいつでも確認できます。

4. Java API

主なJavaAPI機能の使用方法に直接ジャンプする前に、 RestHighLevelClient を開始する必要があります。

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

4.1. ドキュメントのインデックス作成

index()関数を使用すると、任意のJSONドキュメントを保存して、検索可能にすることができます。

@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);
}

任意のJSONJavaライブラリを使用してドキュメントを作成および処理できることに注意してください。これらのいずれにも精通していない場合は、Elasticsearchヘルパーを使用して独自のJSONドキュメントを生成できます[X217X ]:

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. インデックス付きドキュメントのクエリ

型指定された検索可能なJSONドキュメントのインデックスが作成されたので、 search()メソッドを使用して続行および検索できます。

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

search()メソッドによって返される結果はHits と呼ばれ、各Hitは検索リクエストに一致するJSONドキュメントを参照します。

この場合、 results リストには、クラスターに格納されているすべてのデータが含まれています。 この例では、JSON StringsをJavaオブジェクトに変換するためにFastJsonライブラリを使用していることに注意してください。

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. ドキュメントの取得と削除

get()メソッドとdelete ()メソッドを使用すると、IDを使用してクラスターからJSONドキュメントを取得または削除できます。

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);

構文は非常に単純です。オブジェクトのIDと一緒にインデックスを指定する必要があります。

5. QueryBuildersの例

QueryBuilders クラスは、クラスター内の特定のエントリを検索するための動的マッチャーとして使用されるさまざまな静的メソッドを提供します。 search()メソッドを使用してクラスター内の特定のJSONドキュメントを検索する一方で、クエリビルダーを使用して検索結果をカスタマイズできます。

QueryBuildersAPIの最も一般的な使用法のリストを次に示します。

matchAllQuery()メソッドは、クラスター内のすべてのドキュメントに一致するQueryBuilderオブジェクトを返します。

QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

rangeQuery()は、フィールドの値が特定の範囲内にあるドキュメントに一致します。

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

フィールド名の提供–例: fullName 、および対応する値–例: John Doe matchQuery()メソッドは、すべてのドキュメントをこれらの正確なフィールドの値と照合します。

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

multiMatchQuery()メソッドを使用して、一致クエリのマルチフィールドバージョンを作成することもできます。

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

キャレット記号(^)を使用して、特定のフィールドをブーストできます

この例では、 field_2 のブースト値が3に設定されているため、他のフィールドよりも重要です。 ワイルドカードと正規表現クエリを使用することは可能ですが、* _ applesのようなものはパフォーマンスに大きな影響を与える可能性があるため、パフォーマンスに関しては、ワイルドカードを処理する際のメモリ消費と応答時間の遅延に注意してください。

重要係数は、s earch()メソッドの実行後に返されるヒットの結果セットを順序付けるために使用されます。

Luceneクエリの構文に精通している場合は、 simpleQueryStringQuery()メソッドを使用して検索クエリをカスタマイズできます。

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

ご想像のとおり、LuceneのQueryParser構文を使用して、シンプルでありながら強力なクエリを作成できます AND / OR /NOT演算子と一緒に使用して検索クエリを作成できる基本的な演算子を次に示します。

  • 必要な演算子( + ):特定のテキストがドキュメントのフィールドのどこかに存在する必要があります。
  • 禁止演算子():()記号の後に宣言されたキーワードを含むすべてのドキュメントを除外します。

6. 結論

このクイック記事では、ElasticSearchのJava APIを使用して、全文検索エンジンに関連するいくつかの一般的な機能を実行する方法を説明しました。

この記事で提供されている例は、GitHubプロジェクトで確認できます。