查询方法
查询查找策略
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 查询字符串 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
用于构建 Geo-shape 查询的方法名称GeoJson 不支持参数。
用ElasticsearchOperations 跟CriteriaQuery 在自定义存储库实现中,如果您需要在存储库中具有此类函数。 |
方法返回类型
可以将存储库方法定义为具有以下返回类型,用于返回多个 Element:
-
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);
}
设置为 annotation 参数的 String 必须是有效的 Elasticsearch JSON 查询。 它将作为 query 元素的值发送到 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
annotation 替换为 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
,我们可以使用 symbol 而不是 来访问 bean,并且不需要声明 type 为@
#
QueryParameter
在 Query 方法中:
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")
将产生以下 terms 查询:
{
"bool":{
"must":[
{
"terms":{
"name": ["name1", "name2"]
}
}
]
}
}
Collection
参数。当Collection
参数不是普通的String
:
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#parameters.![value]}
}
}
]
}
}
""")
Page<Book> findByName(Collection<QueryParameter> parameters, Pageable pageable);
}
这将提取所有value
property 值作为新的Collection
从QueryParameter
collection 的 intent 中,因此具有与上述相同的效果。
@Param
通过 SpEL 访问参数时,通过以下方式将参数名称更改为另一个名称也很有用@Param
Sping Data 中的注释:
interface BookRepository extends ElasticsearchRepository<Book, String> {
@Query("""
{
"bool":{
"must":[
{
"terms":{
"name": #{#another.![value]}
}
}
]
}
}
""")
Page<Book> findByName(@Param("another") Collection<QueryParameter> parameters, Pageable pageable);
}