You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 20:17:00