ElasticSearch查询:按唯一ID取最新条目并按State聚合统计
解决方案:获取每个ID最新条目并按状态统计
要实现每个唯一ID取最新条目,再按state统计次数的需求,你原查询的问题在于没有先对ID去重并筛选最新条目,直接按state聚合会包含同一ID的历史状态,同时聚合的嵌套结构也有误。
正确查询方式一:使用collapse折叠(推荐)
collapse可以先按id字段分组,提取每个组内timestamp最新的文档,之后的聚合将基于这些去重后的最新文档进行统计:
{ "size": 0, "query": { "bool": { "must": [ { "match": { "projectName": "XYZ" } } ] } }, "collapse": { "field": "id", "inner_hits": { "size": 1, "sort": [ { "timestamp": { "order": "desc" } } ] } }, "aggs": { "state_counts": { "terms": { "field": "state", "size": 50 } } } }
正确查询方式二:多层聚合实现
如果无法使用collapse(比如ES版本较低),可以通过三层聚合实现:
- 按
id分桶,确保每个桶对应唯一ID - 每个ID桶内用
top_hits获取最新的1条文档 - 提取最新文档的
state,再统计各state的次数
{ "size": 0, "query": { "bool": { "must": [ { "match": { "projectName": "XYZ" } } ] } }, "aggs": { "unique_ids": { "terms": { "field": "id", "size": 10000 // 根据实际ID数量调整上限 }, "aggs": { "latest_entry": { "top_hits": { "size": 1, "_source": ["state"], "sort": [ { "timestamp": { "order": "desc" } } ] } }, "latest_state": { "bucket_script": { "buckets_path": { "state": "latest_entry>hits.hits.0._source.state" }, "script": "params.state" } } } }, "state_counts": { "terms": { "script": "params._agg.latest_state", "size": 50 } } } }
结果说明
针对你的示例数据,两种方式都会返回:
Closed:1次(对应ID 9898的最新条目)Implemented:1次(对应ID 999的最新条目)
总计2条统计结果,符合需求。
内容的提问来源于stack exchange,提问作者dablumino
相关产品推荐
相关产品推荐

