【发布时间】:2019-06-19 21:09:20
【问题描述】:
注意:这种查询在2或3年前已经被问过,但没有任何满意的答案。我在这里发布我的具体问题。希望有人提出一些好的解决方案。
我面临从 elasticsearch 获取所需记录的挑战。我们严格需要对 TOP 聚合返回的结果进行过滤。无论如何,下面是我的场景:
鉴于:我们有一个名为“服务”的实体,其属性如下:
{
"id": "servicer-id-1",
"status": "OPEN", // These may be CLOSED, RESOLVED
"timeRaised": "2019-03-21T15:09:17.015Z",
"timeChanged": "2019-03-21T15:09:17.015Z"
}
我有一个弹性索引,其中上述服务的任何更改都存储为整个服务文档(一种服务历史)。具有相同 ID 的服务不止一项。我们每次都更新 timeChanges 属性。
索引中有数百万个服务文档。
问题陈述:我们需要特定的服务,这些服务是在给定时间范围内的最新状态(timeChanged)和状态为 OPEN。
我做了什么: 我使用以下查询和 10000 bacth 大小的滚动 API 来解决我们的问题:
{
"size" : 1000, //given by user
"query" : {
"constant_score" : {
"filter" : {
"bool" : {
"must" : [
{
"range" : {
"timeChanged" : {
"from" : 1552940830000,
"to" : 1553498830000,
"include_lower" : true,
"include_upper" : true,
"boost" : 1.0
}
}
}
],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
"boost" : 1.0
}
},
"post_filter": {
"bool": {
"must": [{
{
"constant_score": {
"filter": {
"terms": {
"status": ["OPEN"],
"boost": 1.0
}
},
"boost": 1.0
}
}
}],
"disable_coord" : false,
"adjust_pure_negative" : true,
"boost" : 1.0
}
},
"_source" : false,
"aggregations" : {
"by_serviceId" : {
"terms" : {
"field" : "id",
"size" : 50000, // we set it with total number of services exist
"min_doc_count" : 1,
"shard_min_doc_count" : 0,
"show_term_doc_count_error" : false,
"order" : [
{
"_count" : "desc"
},
{
"_term" : "asc"
}
]
},
"aggregations" : {
"top" : {
"top_hits" : {
"from" : 0,
"size" : 1,
"version" : false,
"explain" : false,
"sort" : [
{
"timeChanged" : {
"order" : "desc"
}
}
]
}
}
}
}
}
}
从上面的查询中,我们从滚动的第一次命中获得聚合,这是聚合中最新服务状态的列表。通过 Post 过滤器,我们以 10000 个批次获取 OPEN 服务,并尝试将 ids(通过 java 代码)与聚合列表进行匹配以找出我们的候选者。
返回所需的输出花费了太多时间。索引中的 440 万条记录大约需要 8 分钟。
如果您建议一种对返回的聚合数据进行过滤的方法,则可以解决此问题。但是找了这么多地方,发现在elastic中是不支持的。是这样吗? 相同问题的参考:
Elasticsearch: filter top hits aggregation
Elasticsearch exclude top hit on field value
请帮助并提出更好的方法来完成这个场景。
谢谢。
免责声明:请不要建议应用查询然后聚合,因为它不能解决问题。例如如果我先过滤 OPEN 状态然后进行汇总,那么对于给定日期,我总是会获得 OPEN 服务,但实际上对于给定日期,服务可能已解决。
【问题讨论】:
标签: elasticsearch