如何在ElasticSearch中获取每个source_id的最新文档?
解决每个
source_id仅获取最新文档的问题 嗨,我完全懂你的困扰——用普通terms聚合只能拿到计数,没法获取完整的最新文档对吧?其实Elasticsearch有两种常用方案能满足你的需求,我给你一步步拆解:
方法一:使用top_hits聚合(适合聚合分析场景)
这是最直接的解决方案,在你的terms分桶聚合里嵌套一个top_hits子聚合,让它返回每个source_id桶里最新的那1条完整文档。
完整DSL示例
{ "size": 0, // 不需要返回顶层匹配文档,只关注聚合结果 "aggs": { "group_by_source": { "terms": { "field": "source_id.keyword", // 注意用keyword类型字段做分桶(确保是精确匹配) "size": 1000 // 按需设置你需要覆盖的source_id数量上限 }, "aggs": { "latest_document": { "top_hits": { "size": 1, // 每个桶只返回1条最新文档 "sort": [ { "created_on": { "order": "desc" // 按created_on降序排序,第一条就是最新的 } } ], "_source": { // 可选:指定要返回的字段,减少不必要的数据传输 "includes": ["created_on", "source_id", "type", "...其他你需要的字段"] } } } } } } }
结果说明
返回的聚合结果里,每个source_id桶下的latest_document节点就包含了该source_id对应的最新完整文档,你可以直接用这些数据做后续的分析、可视化或者其他处理。
方法二:使用collapse折叠功能(适合直接获取文档列表)
如果你不需要聚合统计,只是想直接拿到所有source_id的最新文档列表,可以用collapse功能——它会在搜索结果层面按source_id折叠,只保留每个分组里的最新文档。
完整DSL示例
{ "query": { "match_all": {} // 这里可以替换成你的业务过滤条件,比如特定type的文档 }, "collapse": { "field": "source_id.keyword", // 按source_id字段折叠分组 "inner_hits": { "size": 1, "sort": [{"created_on": "desc"}] // 每组内取最新的文档 } }, "sort": [{"created_on": "desc"}], // 顶层结果也按时间排序 "size": 1000 // 返回的source_id数量上限 }
结果说明
这种方式返回的hits列表里,每个source_id只会出现一次,对应的inner_hits字段就是该source_id的最新完整文档。
在Kibana里的实操技巧
如果要在Kibana中落地:
- 在Visualize创建图表时,先选择Terms聚合(按
source_id.keyword分桶),再添加子聚合为Top Hits,配置好排序规则和返回字段即可生成基于最新文档的饼图或其他可视化。 - 在Discover里,你可以通过添加自定义聚合面板,或者直接把上述DSL作为自定义查询,过滤出仅包含每个source_id最新文档的数据集。
内容的提问来源于stack exchange,提问作者slim
相关产品推荐
相关产品推荐

