如何使用Elasticsearch多术语聚合检索重复文档?
解决思路
错误原因
multi_terms聚合是Elasticsearch 7.11版本才新增的功能,你当前使用的ES版本低于这个版本,所以会报“未知聚合类型”的错误。
方案一:嵌套Terms聚合(兼容所有ES版本)
通过两层嵌套的terms聚合,先按key1分组,再在每个key1分组下按key2分组,最后筛选出子分组中文档数≥2的组合。
查询示例:
GET /my_index/_search { "size": 0, "aggs": { "key1_groups": { "terms": { "field": "key1", "min_doc_count": 2, // 先过滤出key1出现≥2次的分组,减少计算量 "size": 1000000 }, "aggs": { "key2_groups": { "terms": { "field": "key2", "min_doc_count": 2, // 筛选出key1+key2组合出现≥2次的分组 "size": 1000000 } } } } } }
返回结果中,key1_groups.buckets下的每个桶里,key2_groups.buckets中doc_count≥2的条目,就是你要找的重复key1+key2组合。
方案二:升级ES版本后使用multi_terms聚合
如果可以将ES版本升级到7.11及以上,你最初写的multi_terms聚合查询是有效的,它会直接按key1和key2的组合分组,找出重复的组合:
GET /my_index/_search { "size": 0, "aggs": { "receipts": { "multi_terms": { "terms": [ {"field": "key1"}, {"field": "key2"} ], "min_doc_count": 2, "size": 1000000 } } } }
方案三:用脚本生成组合键聚合(通用方案)
通过脚本将key1和key2拼接成一个唯一组合键,再对这个组合键做terms聚合,同样能定位重复文档:
GET /my_index/_search { "size": 0, "aggs": { "duplicate_combinations": { "terms": { "script": { "source": "doc['key1'].value + '|' + doc['key2'].value" }, "min_doc_count": 2, "size": 1000000 } } } }
注意:如果key1或key2是数值类型,需要先转为字符串,比如doc['key1'].value.toString()。
后续获取重复文档
拿到重复的key1+key2组合后,用以下查询可以导出具体的重复文档:
GET /my_index/_search { "query": { "bool": { "should": [ {"bool": {"must": [{"term": {"key1": "重复值1"}}, {"term": {"key2": "重复值2"}}]}}, // 可以添加更多重复组合 {"bool": {"must": [{"term": {"key1": "重复值3"}}, {"term": {"key2": "重复值4"}}]}} ] } } }
内容的提问来源于stack exchange,提问作者Paolo Magnani
相关产品推荐
相关产品推荐

