elasticsearch - 嵌套对象中日期时间范围的 Elasticsearch 查询问题
问题描述
嗨,我正在使用 spring data Elasticsearch 来形成查询,并在我的弹性搜索中索引了以下数据
索引数据
[
{
"id": "Ef5E-HYB3sZzelDP-ie1",
"name": "B",
"availability": [
{
"partial": false,
"dates": {
"gte": "2020-12-05T09:00:00",
"lte": "2020-12-10T13:00:00"
}
}
]
},
{
"id": "Ev5F-HYB3sZzelDPIicy",
"name": "A",
"availability": [
{
"partial": false,
"dates": {
"gte": "2020-12-01T07:00:00",
"lte": "2020-12-02T12:00:00"
}
}
]
}
]
实体
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.date_hour_minute_second)
private Map<String, LocalDateTime> dates;
}
查询条件:我想查询并检查日期时间之间是否有可用的工作人员:
{
"startDate": "2020-12-05T09:00:00",
"endDate": "2020-12-10T10:00:00"
}
为此,我正在使用 bool 查询和嵌套查询创建一个查询,如下所示:
private Query prepareSearchQuery(final WorkerQuery query, Integer pageNumber, Integer pageSize) {
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// To form the nested query
NestedQueryBuilder nested = prepareAvailabilityQuery(query);
queryBuilder.must(nested);
Pageable pageable = PageRequest.of(pageNumber, pageSize);
// @formatter:off
return new NativeSearchQueryBuilder()
.withPageable(pageable)
.withQuery(queryBuilder)
.build();
// @formatter:on
}
/**
* Query to prepare the nested object structure
*
* @param query
* @return
*/
private NestedQueryBuilder prepareAvailabilityQuery(final WorkerQuery query) {
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// Add date query
if (isValidDateTime(query.getStartDate(), query.getStartDate())) { // validate the datetime obj
// @formatter:off
RangeQueryBuilder dateQuery = QueryBuilders.rangeQuery("availability.dates")
.gte(query.getStartDate())
.lte(query.getEndDate())
// This is not working with date-time
.relation("WITHIN");
// @formatter:on
queryBuilder.must(dateQuery);
}
return QueryBuilders.nestedQuery("availability", queryBuilder, ScoreMode.None);
}
对于这种特殊情况,当我注释掉relation("WITHIN")
我能够获取查询条件的结果时,但是当查询中包含关系时,它不会返回任何结果。查询有问题吗?
注意:我还添加了转换器以在读取和写入数据时将日期时间转换为 Long 和 Back。
这是供参考的存储库
更新
我更新了我的搜索查询以考虑索引数据的timezone
和format
。
private NestedQueryBuilder prepareAvailabilityQuery(final WorkerQuery query) {
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
// queryBuilder.must(QueryBuilders.termQuery("availability.partial", query.isPartial()));
// Add date query
if (isValidDateTime(query.getStartDate(), query.getStartDate())) {
// @formatter:off
RangeQueryBuilder dateQuery = QueryBuilders.rangeQuery("availability.dates")
.gte(query.getFormattedStartDate())
.lte(query.getFormattedEndDate())
.format("yyyy-MM-dd'T'HH:mm")
.timeZone("Asia/Kolkata");
// This is not working with date-time
// .relation("WITHIN");
// @formatter:on
queryBuilder.must(dateQuery);
}
return QueryBuilders.nestedQuery("availability", queryBuilder, ScoreMode.None);
}
所以现在形成的弹性查询对于范围查询来说就像这样:
{
"range": {
"availability.dates": {
"from": "2020-12-01T07:00",
"to": "2020-12-02T12:00",
"include_lower": true,
"include_upper": true,
"time_zone": "Asia/Kolkata",
"format": "yyyy-MM-dd'T'HH:mm",
"boost": 1.0
}
}
}
弹性搜索worker
索引中的索引映射
{
"workers": {
"aliases": {},
"mappings": {
"properties": {
"_class": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"availability": {
"type": "nested",
"properties": {
"dates": {
"type": "date_range"
},
"partial": {
"type": "boolean"
}
}
},
"name": {
"type": "text"
}
}
},
"settings": {
"index": {
"routing": {
"allocation": {
"include": {
"_tier_preference": "data_content"
}
}
},
"refresh_interval": "1s",
"number_of_shards": "1",
"provided_name": "workers",
"creation_date": "1610515965426",
"store": {
"type": "fs"
},
"number_of_replicas": "1",
"uuid": "gJ9zzWs1RXmevJbwwj9Z2g",
"version": {
"created": "7100199"
}
}
}
}
}
解决方案
推荐阅读
- aws-cdk - 无法在安装了 python 的 Windows 上运行 cdk 命令
- html - HTML CSS 的最大宽度
- sql - 当很多列可以有重复数据时如何去除冗余?
- filter - 如何深入比较地图以过滤 XQuery 中的不同项目?
- flutter - 以下两种代码在执行效率方面哪个更好?
- javascript - JavaScript 将两个变量的值放入数组中
- python - 在 Python scikit-learn 上使用自定义权重的最近邻
- python-3.x - HTTPSConnectionPool(host='api.twitter.com', port=443): url 超出最大重试次数
- c - 简单的 C 程序,奇怪的输出
- python - 如何为python的本地wifi多人游戏设置服务器