Elasticsearch 查询带有日期的对象数组
Elasticsearch query on array of objects with date
您好,我是 Elasticsearch 的新手,正在尝试使用 spring-data-elasticsearch
实施解决方案。我的索引数据如下所示:
[
{
"worker": "A",
"availability": [
{
"startDate": "2020-01-12",
"endDate": "2020-02-12"
},
{
"startDate": "2020-04-12",
"endDate": "2020-05-12"
}
]
},
{
"worker": "B",
"availability": [
{
"startDate": "2020-04-12",
"endDate": "2020-11-12"
}
]
}
]
通过参考弹性文档,我计划使用范围查询来获取指定日期范围内的记录,例如,我想获取“2020-05-12 到 2020-06-12”之间的可用工作人员.这是我形成的查询:
{
"query": {
"bool": {
"must": [
{
"nested": {
"query": {
"range": {
"availability.start_date": {
"from": "2020-05-12T00:00:00.000Z",
"to": "2020-06-12T00:00:00.000Z",
"include_lower": true,
"include_upper": true,
"boost": 1.0
}
}
},
"path": "availability",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
}
上面的查询在执行时显示空命中,但是当我使用索引的日期时,我能够获取记录(例如,如果我将日期指定为“2020-04-12 到 2020-11 -12”显示工人 B 结果)。根据范围查询,如果我没记错的话,它也应该适用于我之前的案例。我遵循的方法有什么问题吗?请指教
您没有 start_date
(!!) 介于 2020-05-12
和 2020-06-12
之间的工人。我认为您需要采取不同的方式来实现您想要实现的目标。
由于您尝试匹配范围,因此利用 date_range
field type 可能会更容易。您的映射应如下所示:
PUT your-index
{
"mappings": {
"properties": {
"availability": {
"type": "date_range",
"format": "yyyy-MM-dd"
}
}
}
}
然后您可以像这样索引所有工作人员的可用性:
{
"worker": "A",
"availability": [
{
"gte": "2020-01-12",
"lte": "2020-02-12"
},
{
"gte": "2020-04-12",
"lte": "2020-05-12"
}
]
}
{
"worker": "B",
"availability": [
{
"gte": "2020-04-12",
"lte": "2020-11-12"
}
]
}
然后您可以像这样执行您想要的搜索:
{
"query": {
"range": {
"availability": {
"gte": "2020-05-12",
"lte": "2020-06-12",
"relation": "contains"
}
}
}
}
你会发现只有工人 B 满足条件。
更新
您在 Java 中的查询需要像这样:
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.matchQuery("name", "A"));
RangeQueryBuilder availability = QueryBuilders.rangeQuery("availability")
.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();
您好,我是 Elasticsearch 的新手,正在尝试使用 spring-data-elasticsearch
实施解决方案。我的索引数据如下所示:
[
{
"worker": "A",
"availability": [
{
"startDate": "2020-01-12",
"endDate": "2020-02-12"
},
{
"startDate": "2020-04-12",
"endDate": "2020-05-12"
}
]
},
{
"worker": "B",
"availability": [
{
"startDate": "2020-04-12",
"endDate": "2020-11-12"
}
]
}
]
通过参考弹性文档,我计划使用范围查询来获取指定日期范围内的记录,例如,我想获取“2020-05-12 到 2020-06-12”之间的可用工作人员.这是我形成的查询:
{
"query": {
"bool": {
"must": [
{
"nested": {
"query": {
"range": {
"availability.start_date": {
"from": "2020-05-12T00:00:00.000Z",
"to": "2020-06-12T00:00:00.000Z",
"include_lower": true,
"include_upper": true,
"boost": 1.0
}
}
},
"path": "availability",
"ignore_unmapped": false,
"score_mode": "none",
"boost": 1.0
}
}
],
"adjust_pure_negative": true,
"boost": 1.0
}
}
}
上面的查询在执行时显示空命中,但是当我使用索引的日期时,我能够获取记录(例如,如果我将日期指定为“2020-04-12 到 2020-11 -12”显示工人 B 结果)。根据范围查询,如果我没记错的话,它也应该适用于我之前的案例。我遵循的方法有什么问题吗?请指教
您没有 start_date
(!!) 介于 2020-05-12
和 2020-06-12
之间的工人。我认为您需要采取不同的方式来实现您想要实现的目标。
由于您尝试匹配范围,因此利用 date_range
field type 可能会更容易。您的映射应如下所示:
PUT your-index
{
"mappings": {
"properties": {
"availability": {
"type": "date_range",
"format": "yyyy-MM-dd"
}
}
}
}
然后您可以像这样索引所有工作人员的可用性:
{
"worker": "A",
"availability": [
{
"gte": "2020-01-12",
"lte": "2020-02-12"
},
{
"gte": "2020-04-12",
"lte": "2020-05-12"
}
]
}
{
"worker": "B",
"availability": [
{
"gte": "2020-04-12",
"lte": "2020-11-12"
}
]
}
然后您可以像这样执行您想要的搜索:
{
"query": {
"range": {
"availability": {
"gte": "2020-05-12",
"lte": "2020-06-12",
"relation": "contains"
}
}
}
}
你会发现只有工人 B 满足条件。
更新
您在 Java 中的查询需要像这样:
final BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
queryBuilder.must(QueryBuilders.matchQuery("name", "A"));
RangeQueryBuilder availability = QueryBuilders.rangeQuery("availability")
.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();