如何在Elasticsearch中实现基于字段求和的多Term聚合?
如何在Elasticsearch中实现多Term聚合并对指定字段求和?
需求说明
需要对字段f1和f2执行组合聚合,但不统计每组Term对应的文档数量,而是对第三个字段s的值求和。
测试数据
f1 f2 s === === === a a 1 a b 2 b a 2 a b 1 a b 2 a a 1 b b 3 a b 3
尝试的非法写法
曾尝试用multi_term聚合并指定scoring字段,但该写法不合法:
{ "aggs": { "f_1_2_score": { "multi_term": { "terms": [{ "field": "f1" }, {"field": "f2"}], "scoring": { "field": "s" } // 非法部分 } } } }
期望结果
希望得到类似如下的聚合结果,每个(f1,f2)组合对应s的求和值:
... "buckets": [ { "key": ["a", "a"], "key_as_string": "a|a", "doc_score": 2 }, { "key": ["a", "b"], "key_as_string": "a|b", "doc_score": 7 }, { "key": ["b", "a"], "key_as_string": "b|a", "doc_score": 2 }, { "key": ["b", "b"], "key_as_string": "b|b", "doc_score": 3 }, ] ...
实现方案
方案1:嵌套Terms聚合
这是最直观的写法,通过两层terms聚合分别按f1、f2分组,最后在最内层添加sum聚合计算s的总和:
{ "aggs": { "group_by_f1": { "terms": { "field": "f1" }, "aggs": { "group_by_f2": { "terms": { "field": "f2" }, "aggs": { "sum_s_value": { "sum": { "field": "s" } } } } } } } }
返回结果结构示例:
{ ... "aggregations": { "group_by_f1": { "buckets": [ { "key": "a", "doc_count": 6, "group_by_f2": { "buckets": [ { "key": "b", "doc_count": 4, "sum_s_value": { "value": 8 } }, { "key": "a", "doc_count": 2, "sum_s_value": { "value": 2 } } ] } }, { "key": "b", "doc_count": 2, "group_by_f2": { "buckets": [ { "key": "a", "doc_count": 1, "sum_s_value": { "value": 2 } }, { "key": "b", "doc_count": 1, "sum_s_value": { "value": 3 } } ] } } ] } } }
方案2:Composite聚合(更贴近期望结构)
如果想要直接获取所有(f1,f2)组合的求和结果,推荐使用composite聚合,它支持将多个字段作为组合键,返回的结构更接近你设想的multi_term效果,还支持大数据量下的分页:
{ "aggs": { "f1_f2_composite_group": { "composite": { "sources": [ { "f1": { "terms": { "field": "f1" } } }, { "f2": { "terms": { "field": "f2" } } } ] }, "aggs": { "sum_s_value": { "sum": { "field": "s" } } } } } }
返回结果结构示例:
{ ... "aggregations": { "f1_f2_composite_group": { "buckets": [ { "key": { "f1": "a", "f2": "a" }, "doc_count": 2, "sum_s_value": { "value": 2 } }, { "key": { "f1": "a", "f2": "b" }, "doc_count": 4, "sum_s_value": { "value": 8 } }, { "key": { "f1": "b", "f2": "a" }, "doc_count": 1, "sum_s_value": { "value": 2 } }, { "key": { "f1": "b", "f2": "b" }, "doc_count": 1, "sum_s_value": { "value": 3 } } ] } } }
说明
- 嵌套Terms聚合适合需要先查看
f1整体分组,再深入每个f1下的f2分组的场景; - Composite聚合更适合直接获取所有
(f1,f2)组合的扁平化结果,结构更贴近你的期望,且支持分页(通过after参数)。
内容的提问来源于stack exchange,提问作者Nathan Kronenfeld
相关产品推荐
相关产品推荐

