Elasticsearch查询:按分组获取符合指定条件的最新文档
Elasticsearch分组筛选解决方案
明确需求:按ident和version分组,仅保留**组内chdate最大且field1等于指定值x**的分组,并返回对应文档。你的现有查询已实现分组取最新文档,补充筛选逻辑即可,以下是两种可行方案:
方案一:服务端聚合筛选(推荐)
通过嵌套聚合判断每组最新文档是否满足field1=x,仅保留符合条件的分组并返回目标文档,适合大数据量场景。
查询示例(以x=0为例)
{ "size": 0, "aggs": { "by_ident": { "terms": { "field": "ident.keyword", "size": 10 }, "aggs": { "by_version": { "terms": { "field": "version", "size": 10000 }, "aggs": { // 计算当前分组的最大chdate "max_chdate": { "max": { "field": "chdate" } }, // 过滤field1=x的文档,同时计算这些文档的最大chdate和最新文档 "filtered_docs": { "filter": { "term": { "field1": 0 } }, "aggs": { "filtered_max_chdate": { "max": { "field": "chdate" } }, "target_doc": { "top_hits": { "sort": [{"chdate": {"order": "desc"}}], "size": 1, "_source": ["objid", "ident", "version", "chdate", "field1"] } } } }, // 仅保留分组最大chdate与过滤后最大chdate相等的bucket(即最新文档满足field1=x) "include_valid_bucket": { "bucket_selector": { "buckets_path": { "groupMax": "max_chdate", "filteredMax": "filtered_docs>filtered_max_chdate" }, "script": "params.groupMax == params.filteredMax" } } } } } } } }
逻辑说明
- 分层分组:按
ident.keyword和version完成分组,匹配你的需求。 - 全局最新时间计算:
max_chdate聚合获取当前分组的最大chdate值。 - 过滤后数据处理:
filtered_docs聚合仅保留field1=x的文档,同时计算这些文档的最大chdate和最新文档。 - 有效分组筛选:通过
bucket_selector脚本判断,只有当分组全局最大chdate与过滤后最大chdate相等时,才保留该分组——这意味着该分组的最新文档恰好满足field1=x。
当x=1时,只需修改filter中的field1值为1,即可返回objid=1的文档。
方案二:客户端过滤(适合小数据量)
先用你原有的查询获取所有分组的最新文档,再在客户端代码中筛选出field1=x的文档,实现简单但效率较低。
调整后的原查询
{ "size": 0, "aggs": { "by_ident": { "terms": { "field": "ident.keyword", "size": 10 }, "aggs": { "by_version": { "terms": { "field": "version", "size": 10000 }, "aggs": { "latest_doc": { "top_hits": { "sort": [{ "chdate": { "order": "desc" } }], "size": 1, "_source": ["objid", "field1"] } } } } } } } }
遍历聚合结果,仅保留latest_doc.hits.hits[0]._source.field1 == x的文档即可。
内容的提问来源于stack exchange,提问作者M. A. Tanaka
相关产品推荐
相关产品推荐

