クエリメソッド
クエリルックアップ戦略
Elasticsearch モジュールは、文字列クエリ、ネイティブ検索クエリ、条件ベースのクエリ、メソッド名から派生したクエリなど、すべての基本的なクエリ構築機能をサポートします。
宣言されたクエリ
メソッド名からクエリを導出することは必ずしも十分ではなく、メソッド名が判読できない場合があります。この場合、@Query
アノテーションを使用できます ( @Query アノテーションの使用を参照)。
クエリの作成
一般的に、Elasticsearch のクエリ作成メカニズムは、クエリメソッドの定義で説明されているとおりに機能します。Elasticsearch クエリメソッドがどのように変換されるかを示す簡単な例を次に示します。
interface BookRepository extends Repository<Book, String> {
List<Book> findByNameAndPrice(String name, Integer price);
}
上記のメソッド名は、次の Elasticsearch json クエリに変換されます。
{
"query": {
"bool" : {
"must" : [
{ "query_string" : { "query" : "?", "fields" : [ "name" ] } },
{ "query_string" : { "query" : "?", "fields" : [ "price" ] } }
]
}
}
}
Elasticsearch でサポートされているキーワードのリストを以下に示します。
キーワード | サンプル | Elasticsearch クエリ文字列 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
GeoJson パラメーターを受け取る Geo-shape クエリを構築するためのメソッド名はサポートされていません。リポジトリにそのような機能が必要な場合は、カスタムリポジトリ実装で ElasticsearchOperations と CriteriaQuery を使用します。 |
メソッド戻り値の型
リポジトリメソッドは、複数の要素を返すために次の戻り値の型を持つように定義できます。
List<T>
Stream<T>
SearchHits<T>
List<SearchHit<T>>
Stream<SearchHit<T>>
SearchPage<T>
@Query アノテーションの使用
@Query
アノテーションを使用してメソッドのクエリを宣言します。 メソッドに渡される引数は、クエリ文字列のプレースホルダーに挿入できます。プレースホルダーは、最初のパラメーター、2 番目のパラメーター、3 番目のパラメーターなど、?0
、?1
、?2
などの形式になります。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
Page<Book> findByName(String name,Pageable pageable);
}
アノテーション引数として設定される文字列は、有効な Elasticsearch JSON クエリである必要があります。これはクエリ要素の値として Easticsearch に送信されます。たとえば、関数がパラメーター John で呼び出されると、次のクエリ本体が生成されます。
{
"query": {
"match": {
"name": {
"query": "John"
}
}
}
}
@Query
アノテーション 次のようなリポジトリメソッド
@Query("{\"ids\": {\"values\": ?0 }}")
List<SampleEntity> getByIds(Collection<String> ids);
ID クエリ (英語) を作成して、一致するすべてのドキュメントを返します。List
または ["id1", "id2", "id3"]
を指定してメソッドを呼び出すと、クエリ本体が生成されます。
{
"query": {
"ids": {
"values": ["id1", "id2", "id3"]
}
}
}
SpEL 式の使用
@Query
アノテーションを使用してメソッドにクエリを宣言します。@Query
でクエリを定義する場合も、SpEL 式がサポートされます。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{#name}"
}
}
]
}
}
""")
Page<Book> findByName(String name, Pageable pageable);
}
たとえば、関数がパラメーター John で呼び出されると、次のクエリ本体が生成されます。
{
"bool":{
"must":[
{
"term":{
"name": "John"
}
}
]
}
}
クエリパラメーター型として次のクラスがあるとします。
public record QueryParameter(String value) {
}
#
シンボルでパラメーターにアクセスし、単純な .
でプロパティ value
を参照するのは簡単です。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{#parameter.value}"
}
}
]
}
}
""")
Page<Book> findByName(QueryParameter parameter, Pageable pageable);
}
ここで、new QueryParameter("John")
をパラメーターとして渡すと、上記と同じクエリ文字列が生成されます。
Bean プロパティへのアクセスもサポートされています。QueryParameter
型の queryParameter
という名前の Bean がある場合、#
ではなくシンボル @
を使用して Bean にアクセスでき、クエリメソッドで QueryParameter
型のパラメーターを宣言する必要はありません。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"term":{
"name": "#{@queryParameter.value}"
}
}
]
}
}
""")
Page<Book> findByName(Pageable pageable);
}
Collection
パラメーター。Collection
パラメーターもサポートされており、次の terms
クエリのように、通常の String
と同じように簡単に使用できます。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#names}
}
}
]
}
}
""")
Page<Book> findByName(Collection<String> names, Pageable pageable);
}
elasticsearch json クエリを宣言するときに、コレクション値を引用符で囲まないでください。 |
List.of("name1", "name2")
のような names
のコレクションは、次の用語クエリを生成します。
{
"bool":{
"must":[
{
"terms":{
"name": ["name1", "name2"]
}
}
]
}
}
Collection
パラメーターのアクセスプロパティ。SpEL コレクション射影は、Collection
パラメーターの値が単純な String
ではない場合に使用すると便利です。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#parameters.![value]}
}
}
]
}
}
""")
Page<Book> findByName(Collection<QueryParameter> parameters, Pageable pageable);
}
これにより、QueryParameter
コレクションからすべての value
プロパティ値が新しい Collection
として抽出され、上記と同じ効果が得られます。
@Param
を使用してパラメーター名を変更する SpEL でパラメーターにアクセスする場合、Sping Data の @Param
アノテーションを使用してパラメーター名を別の名前に変更することも便利です。
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#another.![value]}
}
}
]
}
}
""")
Page<Book> findByName(@Param("another") Collection<QueryParameter> parameters, Pageable pageable);
}