我有这个类型的实体保存到elasticSearch:
class Value {
private Integer priority;
private Date dueDate;
}
对于优先级,可能的值是1和2(我知道应该使用enum,但让我们不专注于此)。现在使用弹性搜索,我想得到以下结果:
- 今天或过去有多少优先级为1的值
- 我有多少优先级为1的值已dueDate为空或将来
- 有多少优先级为2的值在今天或过去到期
- 我有多少优先级为2的值已dueDate为空或将来
我试着做的是:
SearchRequest request = new SearchRequest.Builder()
.index(MY_INDEX)
.query(getQuery(someKeys))
.aggregations(ELASTIC_AGG_PRIORITY, Aggregation.of(a ->
a.terms(terms -> terms.field(ELASTIC_AGG_PRIORITY).missing(""))))
.build();
这将获得按优先级分组的聚合,并将知道优先级为1和优先级为2的值的数量。但我需要添加嵌套聚合,这是我的问题。如何将这些桶分开,我将其分为过去或今天的dueDate和未来或null的dueDate。此外,我在编写范围查询时遇到问题:
public static Query getRangeQuery(String field) {
return QueryBuilders.range().field(field).lte(JsonData.of(new Date())).build()._toQuery();
}
我不能通过的一年,我不知道如何处理空当我需要选择一切在未来和空值。我尝试了以下操作,但没有得到我需要的结果:
SearchRequest request = new SearchRequest.Builder()
.index(MY_INDEX)
.query(getQuery(someKeys))
.aggregations(ELASTIC_AGG_ASSIGNEE, Aggregation.of(a ->
a.terms(terms -> terms.field(ELASTIC_AGG_ASSIGNEE).missing(""))))
.aggregations(ELASTIC_AGG_PRIORITY, Aggregation.of(a ->
a.terms(terms -> terms.field(ELASTIC_AGG_PRIORITY).missing(""))
.aggregations(ELASTIC_AGG_PRIORITY, Aggregation.of(filterAgg -> filterAgg
.filter(QueryUtil.getRangeQuery("dueDate"))))
)
).build();
其中QueryUtil.getRangeQuery(
为上述方法。
你很接近了,但是你需要实现"date_range_aggregation"得到你想要的结果。
您的术语聚合是ok的,您所需要做的就是将date_range_aggregation作为子聚合添加到术语聚合。
为您的"null"值,设置一个"缺失";作为过去的事物的价值。这样你就可以把它作为第三个桶。
样本(json):
{
"aggs": {
"range": {
"date_range": {
"field": "date",
"missing": "1976/11/30",
"ranges": [
{
"key": "Oldest",
"to" : "1976/11/30"
},
{
"key": "Past",
"from" : "1976/11/30"
"to": "now"
},
{
"key": "Future",
"from": "now"
}
]
}
}
}
}
让我知道这是否适合你。