| 此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Data Elasticsearch 5.5.2! | 
查询方法
查询查找策略
Elasticsearch 模块支持所有基本查询构建功能,如字符串查询、本机搜索查询、基于条件的查询或从方法名称派生。
声明的查询
从方法名称派生查询并不总是足够的,和/或可能导致方法名称不可读。
在这种情况下,可以使用@Query注释(请参阅使用@Query注释)。
另一种可能性是使用搜索模板(请参阅使用@SearchTemplateQuery注释)。
查询创建
通常,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不支持参数。
用ElasticsearchOperations跟CriteriaQuery如果您需要在存储库中具有此类函数,请在自定义存储库实现中。 | 
方法返回类型
可以将存储库方法定义为具有以下返回类型以返回多个元素:
- 
List<T>
- 
Stream<T>
- 
SearchHits<T>
- 
List<SearchHit<T>>
- 
Stream<SearchHit<T>>
- 
SearchPage<T>
使用@Query注释
@Query注解。传递给该方法的参数可以插入到查询字符串中的占位符中。
占位符的形式为?0,?1,?2等等。
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("{\"match\": {\"name\": {\"query\": \"?0\"}}}")
    Page<Book> findByName(String name,Pageable pageable);
}设置为注释参数的 String 必须是有效的 Elasticsearch JSON 查询。 它将作为查询元素的值发送到 Easticsearch;例如,如果使用参数 John 调用函数,它将生成以下查询正文:
{
  "query": {
    "match": {
      "name": {
        "query": "John"
      }
    }
  }
}@Query对采用 Collection 参数的方法进行注释存储库方法,例如
@Query("{\"ids\": {\"values\": ?0 }}")
List<SampleEntity> getByIds(Collection<String> ids);将进行 IDs 查询以返回所有匹配的文档。
因此,使用List之["id1", "id2", "id3"]将生成查询正文
{
  "query": {
    "ids": {
      "values": ["id1", "id2", "id3"]
    }
  }
}使用 SpEL 表达式
@Query带有 SpEL 表达式的注释。在定义查询时也支持 SpEL 表达式@Query.
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,我们可以使用 symbol 而不是 来访问 bean,并且不需要声明类型为@#QueryParameter在查询方法中:
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("""
            {
              "bool":{
                "must":[
                  {
                    "term":{
                      "name": "#{@queryParameter.value}"
                    }
                  }
                ]
              }
            }
            """)
    Page<Book> findByName(Pageable pageable);
}Collection参数。Collection参数也支持,并且与正常情况一样易于使用String,例如以下内容terms查询:
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("""
            {
              "bool":{
                "must":[
                  {
                    "terms":{
                      "name": #{#names}
                    }
                  }
                ]
              }
            }
            """)
    Page<Book> findByName(Collection<String> names, Pageable pageable);
}| 声明 Elasticsearch JSON 查询时,不应将集合值加引号。 | 
集合names喜欢List.of("name1", "name2")将生成以下术语查询:
{
  "bool":{
    "must":[
      {
        "terms":{
          "name": ["name1", "name2"]
        }
      }
    ]
  }
}Collection参数。SpEL Collection Projection 在Collection参数不是普通的String:
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("""
            {
              "bool":{
                "must":[
                  {
                    "terms":{
                      "name": #{#parameters.![value]}
                    }
                  }
                ]
              }
            }
            """)
    Page<Book> findByName(Collection<QueryParameter> parameters, Pageable pageable);
}这将提取所有value属性值作为新的Collection从QueryParameter集合,因此具有与上述相同的效果。
@Param当通过 SpEL 访问参数时,通过以下方式将参数名称更改为另一个参数名称也很有用@ParamSping Data 中的注释:
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @Query("""
            {
              "bool":{
                "must":[
                  {
                    "terms":{
                      "name": #{#another.![value]}
                    }
                  }
                ]
              }
            }
            """)
    Page<Book> findByName(@Param("another") Collection<QueryParameter> parameters, Pageable pageable);
}使用@SearchTemplateQuery注释
使用 Elasticsearch 搜索模板时 - (请参阅搜索模板支持)可以通过添加@SearchTemplateQuery注释到该方法。
假设有一个名为“book-by-title”的搜索模板存储,并且该模板需要一个名为“title”的参数,那么可以使用该搜索模板的存储库方法可以定义如下:
interface BookRepository extends ElasticsearchRepository<Book, String> {
    @SearchTemplateQuery(id = "book-by-title")
    SearchHits<Book> findByTitle(String title);
}存储库方法的参数作为键/值对发送到 seacrh 模板,其中键是参数名称,调用方法时取自实际值。