Elasticsearch オペレーション
Spring Data Elasticsearch は、Elasticsearch インデックスに対して呼び出すことができる操作を定義するためにいくつかのインターフェースを使用します (リアクティブインターフェースの説明については、リアクティブ型 Elasticsearch オペレーションを参照してください)。
IndexOperations
(Javadoc) は、インデックスの作成や削除などのインデックスレベルでのアクションを定義します。DocumentOperations
(Javadoc) は、ID に基づいてエンティティを保存、更新、取得するアクションを定義します。SearchOperations
(Javadoc) はクエリを使用して複数のエンティティを検索するアクションを定義しますElasticsearchOperations
(Javadoc) は、DocumentOperations
とSearchOperations
インターフェースを組み合わせたものです。
これらのインターフェースは、Elasticsearch API (英語) の構造に対応します。
インターフェースのデフォルト実装は以下を提供します。
インデックス管理機能。
ドメイン型の読み取り / 書き込みマッピングのサポート。
豊富なクエリと条件 API。
リソース管理と例外の変換。
インデックス管理、インデックスとマッピングの自動作成。
Spring Data Elasticsearch リポジトリを使用する場合、インデックスの自動作成とマッピングの書き込みがサポートされています。対応するマッピングを使用したインデックスの自動作成を参照してください。 |
使用例
この例では、挿入された ElasticsearchOperations
インスタンスを Spring REST コントローラーで使用する方法を示します。この例では、Person
が @Document
、@Id
などのアノテーションが付けられたクラスであると想定しています ( マッピングアノテーションの概要を参照)。
@RestController
@RequestMapping("/")
public class TestController {
private ElasticsearchOperations elasticsearchOperations;
public TestController(ElasticsearchOperations elasticsearchOperations) { (1)
this.elasticsearchOperations = elasticsearchOperations;
}
@PostMapping("/person")
public String save(@RequestBody Person person) { (2)
Person savedEntity = elasticsearchOperations.save(person);
return savedEntity.getId();
}
@GetMapping("/person/{id}")
public Person findById(@PathVariable("id") Long id) { (3)
Person person = elasticsearchOperations.get(id.toString(), Person.class);
return person;
}
}
1 | Spring が、提供された ElasticsearchOperations Bean をコンストラクターに挿入します。 |
2 | Elasticsearch クラスターにいくつかのエンティティを保存します。ID は返されたエンティティから読み取られます。これは、person オブジェクトでは null であり、Elasticsearch によって作成された可能性があるからです。 |
3 | ID による取得を使用してエンティティを取得します。 |
ElasticsearchOperations
の可能性をすべて確認するには、API ドキュメントを参照してください。
検索結果の種類
DocumentOperations
インターフェースのメソッドを使用してドキュメントを取得すると、見つかったエンティティのみが返されます。SearchOperations
インターフェースのメソッドを使用して検索する場合、見つかったエンティティのスコアや sortValues など、各エンティティの追加情報が利用できます。
この情報を返すために、各エンティティは、このエンティティ固有の追加情報を含む SearchHit
オブジェクトにラップされます。これらの SearchHit
オブジェクト自体は、maxScore やリクエストされた集計、またはリクエストを完了するのにかかった実行時間などの検索全体に関する情報も含む SearchHits
オブジェクト内で返されます。現在、次のクラスとインターフェースが利用可能です。
次の情報が含まれます。
ID
スコア
値の並べ替え
強調表示フィールド
インナーヒット (これは、最終的に返される内部ヒットを含む埋め込み
SearchHits
オブジェクトです。)型 <T> の取得されたエンティティ
次の情報が含まれます。
総ヒット数
総ヒット数関係
最大スコア
SearchHit<T>
オブジェクトのリスト返された集計
返された提案結果
SearchHits<T>
要素を含み、リポジトリメソッドを使用したページングアクセスに使用できる Spring Data Page
を定義します。
ElasticsearchRestTemplate
の低レベルスクロール API 関数によって返され、Elasticsearch スクロール ID で SearchHits<T>
を強化します。
SearchOperations
インターフェースのストリーミング関数によって返されるイテレーター。
ReactiveSearchOperations
には Mono<ReactiveSearchHits<T>>
を返すメソッドがあり、これには SearchHits<T>
オブジェクトと同じ情報が含まれますが、含まれる SearchHit<T>
オブジェクトはリストとしてではなく Flux<SearchHit<T>>
として提供されます。
照会
SearchOperations
および ReactiveSearchOperations
インターフェースで定義されているメソッドのほとんどすべては、検索のために実行するクエリを定義する Query
パラメーターを取ります。Query
はインターフェースであり、Spring Data と Elasticsearch は 3 つの実装 (CriteriaQuery
、StringQuery
、NativeQuery
) を提供します。
CriteriaQuery
CriteriaQuery
ベースのクエリを使用すると、Elasticsearch クエリの構文や基本を知らなくても、データを検索するクエリを作成できます。ユーザーは、検索対象のドキュメントが満たす必要のある条件を指定する Criteria
オブジェクトを単純に連鎖して組み合わせるだけで、クエリを構築できます。
AND または OR について話すとき、条件を組み合わせる際に、Elasticsearch では AND は必須条件に変換され、OR は推奨条件に変換されることに留意してください。 |
Criteria
とその使用箇所は、例によって最もよく説明されます (price
プロパティを持つ Book
エンティティがあると仮定しましょう)。
Criteria criteria = new Criteria("price").is(42.0);
Query query = new CriteriaQuery(criteria);
同じフィールドの条件は連鎖させることができ、論理 AND で結合されます。
Criteria criteria = new Criteria("price").greaterThan(42.0).lessThan(34.0);
Query query = new CriteriaQuery(criteria);
Criteria
をチェーンする場合、デフォルトでは AND ロジックが使用されます。
Criteria criteria = new Criteria("lastname").is("Miller") (1)
.and("firstname").is("James") (2)
Query query = new CriteriaQuery(criteria);
1 | 最初の Criteria |
2 | and() は新しい Criteria を作成し、それを最初の Criteria にチェーンします。 |
ネストされたクエリを作成する場合は、サブクエリを使用する必要があります。Miller という姓と Jack または John という名前を持つすべての人物を検索したいと仮定します。
Criteria miller = new Criteria("lastName").is("Miller") (1)
.subCriteria( (2)
new Criteria().or("firstName").is("John") (3)
.or("firstName").is("Jack") (4)
);
Query query = new CriteriaQuery(criteria);
1 | 姓に対して最初の Criteria を作成する |
2 | これを AND で subCriteria に組み合わせる |
3 | このサブ条件は、名 John の OR の組み合わせです。 |
4 | そして名前はジャックです |
利用可能なさまざまな操作の完全な概要については、Criteria
クラスの API ドキュメントを参照してください。
StringQuery
このクラスは、Elasticsearch クエリを JSON 文字列として受け取ります。次のコードは、名前が "Jack" である人物を検索するクエリを示しています。
Query query = new StringQuery("{ \"match\": { \"firstname\": { \"query\": \"Jack\" } } } ");
SearchHits<Person> searchHits = operations.search(query, Person.class);
すでに Elasticsearch クエリを使用している場合は、StringQuery
を使用するのが適切です。
NativeQuery
NativeQuery
は、クエリを構築して集約を使用する場合など、複雑なクエリや、Criteria
API を使用して表現できないクエリがある場合に使用するクラスです。これにより、Elasticsearch ライブラリのさまざまな co.elastic.clients.elasticsearch._types.query_dsl.Query
実装をすべて使用できるため、「ネイティブ」という名前が付けられています。
次のコードは、特定の firstName
を持つ人物を検索し、見つかったドキュメントについて、これらの人物の lastName
の出現数をカウントする用語集計を行う方法を示しています。
Query query = NativeQuery.builder()
.withAggregation("lastNames", Aggregation.of(a -> a
.terms(ta -> ta.field("lastName").size(10))))
.withQuery(q -> q
.match(m -> m
.field("firstName")
.query(firstName)
)
)
.withPageable(pageable)
.build();
SearchHits<Person> searchHits = operations.search(query, Person.class);
SearchTemplateQuery
これは、格納された検索テンプレートと組み合わせて使用される Query
インターフェースの特別な実装です。詳細については、検索テンプレートのサポートを参照してください。