Elasticsearch Bool查询添加聚合后结果未变,如何按display_name去重?
解决Elasticsearch聚合未改变搜索结果的问题
嘿,我来帮你理清这个问题~你遇到的核心点是聚合和搜索结果是两个独立的部分:你添加的terms聚合只是用来统计每个display_name.keyword的出现频次,但它不会自动过滤或修改返回的原始文档列表(也就是你看到的device-resource部分)。聚合结果其实会单独出现在响应的aggregations字段里,只是你可能没注意到它。
如果你的目标是让返回的文档按display_name去重(每个名称只保留一条),有两种更合适的方案:
方案1:使用collapse字段折叠(最直接)
Elasticsearch提供了collapse参数,专门用来对搜索结果按指定字段去重,直接修改你的查询即可:
{ "query": { "bool": { "filter": [ { "terms": { "parent_uuid._raw": [ "87ec596a-109e-45ce-8a8d-7a2d1a56df81", "07526608-8140-46be-96b9-c5f7cca4bd93" ] } }, { "terms": { "resource_type._raw": [ "Zone" ] } } ] } }, "from": 0, "collapse": { "field": "display_name.keyword" } }
这个查询会返回:
device-resource里仅包含每个display_name.keyword分组的第一条文档total字段会显示去重后的总数(也就是你期望的3)
方案2:使用top_hits聚合(更灵活)
如果你需要更精细的控制(比如指定返回分组里的哪条文档,或者同时统计分组数量),可以用top_hits聚合配合terms聚合,这种方式需要把聚合结果作为你要的输出:
{ "query": { "bool": { "filter": [ { "terms": { "parent_uuid._raw": [ "87ec596a-109e-45ce-8a8d-7a2d1a56df81", "07526608-8140-46be-96b9-c5f7cca4bd93" ] } }, { "terms": { "resource_type._raw": [ "Zone" ] } } ] } }, "size": 0, // 关闭原始搜索结果返回,只保留聚合数据 "aggs": { "group_by_name": { "terms": { "field": "display_name.keyword", "size": 10 // 根据你的分组数量调整这个值 }, "aggs": { "top_device": { "top_hits": { "size": 1 // 每个分组只返回1条文档 } } } } } }
执行后,你需要从响应的aggregations.group_by_name.buckets中提取数据:每个bucket的key是display_name的值,top_device.hits.hits里就是该分组对应的文档。这种方式适合需要同时获取分组统计和对应文档的场景。
总结
你之前的操作只是添加了统计用的聚合,但没有修改搜索结果的返回逻辑。用collapse可以快速实现文档去重的需求,而top_hits聚合适合更复杂的分组场景。
内容的提问来源于stack exchange,提问作者Vaibhav
相关产品推荐
相关产品推荐

