【问题标题】:Elasticsearch query on array of composite objects along with date ranges对复合对象数组以及日期范围的 Elasticsearch 查询
【发布时间】:2021-04-17 03:42:09
【问题描述】:

您好,我有一个关于如何为具有日期范围和其他字段参数的嵌套复合对象创建弹性搜索查询的问题

[{
            "name": "A",
            "availability": [
                {
                    "partial": true,
                    "dates": {
                        "gte": "2020-12-01",
                        "lte": "2020-12-02"
                    }
                }
            ]
        },
        {
            "name": "B",
            "availability": [
                {
                    "partial": true,
                    "dates": {
                        "gte": "2020-12-05",
                        "lte": "2020-12-06"
                    }
                },
                {
                    "partial": false,
                    "dates": {
                        "gte": "2020-12-08",
                        "lte": "2020-12-11"
                    }
                }
            ]
        }]

这是我的实体数据

@Document(indexName = "workers")
public class Worker {
    @Id
    private String id;

    @Field(type = FieldType.Text)
    private String name;

    @Field(type = FieldType.Nested)
    private List<Availability> availability;
}

public class Availability {
    @Field(type = FieldType.Boolean)
    private boolean partial;
    
    @Field(type = FieldType.Date_Range, format = DateFormat.custom, pattern = "uuuu-MM-dd")
    private Map<String, LocalDate> dates;
}


这是我目前编写的搜索查询,但结果为空

         final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.termQuery("availability.partial", query.isPartial()));
         
         RangeQueryBuilder availability = QueryBuilders.rangeQuery("availability.dates")
                   .gte(query.getStartDate())
                   .lte(query.getEndDate());
queryBuilder.must(availability);
        
        Pageable pageable = PageRequest.of(pageNumber, pageSize);

        // @formatter:off
        return new NativeSearchQueryBuilder()
                .withPageable(pageable)
                .withQuery(queryBuilder)
                .build();

这是我的查询 dto

public class WorkerQuery {
    private boolean partial;
    private LocalDate startDate;
    private LocalDate endDate;
}

// Request data
{
    "partial": true,
    "startDate": "2020-12-01",
    "endDate": "2020-12-02"
}

【问题讨论】:

    标签: elasticsearch spring-data-elasticsearch


    【解决方案1】:

    伟大的开始!因为availabilitynested,所以您只是缺少nested 查询。 Java 查询需要是这样的:

    final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    queryBuilder.must(QueryBuilders.termQuery("availability.partial", query.isPartial()));
    
    RangeQueryBuilder availability = QueryBuilders.rangeQuery("availability.dates")
                   .gte(query.getStartDate())
                   .lte(query.getEndDate())
                   .relation("within");
    queryBuilder.must(availability);
    
    final NestedQueryBuilder nested = QueryBuilders.nestedQuery("availability", queryBuilder);
    
    Pageable pageable = PageRequest.of(pageNumber, pageSize);
    
    // @formatter:off
    return new NativeSearchQueryBuilder()
                .withPageable(pageable)
                .withQuery(nested)
                .build();
    

    【讨论】:

    • 你是救生员@Val :) 现在它按预期工作。但是我对您在上面形成的查询有一个问题。 nested 查询是否必须是根查询对象?可以仅应用于嵌套的availability 对象吗?
    • 我已将它添加到根目录,因为您没有任何其他限制。如果您要在 worker 字段上添加约束,那么您需要一个根 bool 查询,嵌套查询将与顶级工作字段上的新约束一起成为它的一个组件
    • 知道了 :) 非常感谢您提供的信息
    • 嗨@Val 我已经更新了我的查询here如果我做得对请告诉我?
    • 对,就是other way aroundwithin是正确的使用关系,好抓!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2019-07-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多