Elasticsearch如何按字段分组统计嵌套结构内另一字段值总和
问题原因说明
你之前的尝试存在两个核心问题:
value_count聚合的作用是统计字段非空值的个数,无法实现数值求和,且你语句中指定的字段为admin_id,和需求统计的vat字段无关,自然返回错误结果。- 嵌套(nested)聚合语法错误:
nested聚合层级仅支持配置path参数,不能直接写入query配置;且你未在嵌套上下文中定义分组、求和的子聚合逻辑,因此触发语法报错。
注意:使用该方案前请确认索引mapping中
rows字段已被设置为nested类型。如果使用默认的object类型存储数组,Elasticsearch会扁平化存储数组内的字段值,丢失vat_percentage和vat的一一对应关系,统计结果会出现偏差。
正确实现语句
{ "size": 0, "aggs": { "vat_agg": { "nested": { "path": "rows" }, "aggs": { "group_by_percentage": { "terms": { "field": "rows.vat_percentage" }, "aggs": { "vat_sum": { "sum": { "field": "rows.vat" } } } } } } } }
结果处理
执行上述语句后,聚合结果存放在返回值的aggregations.vat_agg.group_by_percentage.buckets路径下,每个bucket的示例结构如下:
{ "key": 9.0, "doc_count": 2, "vat_sum": { "value": 2.93 } }
遍历buckets数组,将每个元素的key映射为vat_percentage,vat_sum.value映射为vat_sum,即可得到你期望的输出格式。
扩展:需要过滤嵌套文档时的写法
如果你需要先筛选符合条件的rows子文档再做聚合(比如仅统计vat大于1的条目),可以在nested聚合内部增加filter聚合层,示例如下:
{ "size": 0, "aggs": { "vat_agg": { "nested": { "path": "rows" }, "aggs": { "filter_vat_gt1": { "filter": { "range": { "rows.vat": { "gt": 1 } } }, "aggs": { "group_by_percentage": { "terms": { "field": "rows.vat_percentage" }, "aggs": { "vat_sum": { "sum": { "field": "rows.vat" } } } } } } } } } }
内容的提问来源于stack exchange,提问作者Samball
相关产品推荐
相关产品推荐

