如何在Elasticsearch中对数组字段值执行不去重的聚合统计?
统计Elasticsearch数组字段元素总出现次数(含重复值)
问题场景
我有如下文档:
[{ "title": "Document 1", "tags": ["elasticsearch", "aggregation", "elasticsearch"] }, { "title": "Document 2", "tags": ["elasticsearch", "search", "search"] }, { "title": "Document 3", "tags": ["aggregation", "search"] }]
执行常规terms聚合请求:
{ "size": 0, "aggs": { "tags_count": { "terms": { "field": "tags.keyword" } } } }
期望得到每个标签的总出现次数(包含同一文档内的重复值):
{ "aggregations": { "tags_count": { "buckets": [ { "key": "elasticsearch", "doc_count": 3 }, { "key": "search", "doc_count": 3 }, { "key": "aggregation", "doc_count": 2 } ] } } }
但实际返回的是标签出现的文档数(去重计数):
{ "aggregations": { "tags_count": { "buckets": [ { "key": "elasticsearch", "doc_count": 2 }, { "key": "search", "doc_count": 2 }, { "key": "aggregation", "doc_count": 2 } ] } } }
解决方案
默认terms聚合按包含该标签的文档数量计数,而非标签的总出现次数。要实现预期效果,需通过脚本遍历数组中的每个元素并单独输出,让聚合统计每个元素的总出现次数。
修改后的聚合请求:
{ "size": 0, "aggs": { "tags_count": { "terms": { "script": { "source": "for (tag in doc['tags.keyword']) { emit(tag); }" }, "size": 10 // 根据实际需求调整返回的桶数量 } } } }
该脚本会逐个输出数组中的每个标签元素,terms聚合据此统计每个标签的总出现次数,最终得到预期结果。
内容的提问来源于stack exchange,提问作者Finn Llewellyn
相关产品推荐
相关产品推荐

