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

ElasticSearch:聚合时如何拼接数组元素?

如何在Elasticsearch中聚合拼接数组字段

当然能实现!你要的这种按email聚合并拼接所有相关error_codes数组的需求,用Elasticsearch的scripted_metric聚合就能搞定——这是处理这类自定义数组合并场景的绝佳方案,比普通的数值聚合灵活得多。

完整的聚合DSL示例

下面是直接可用的查询语句,会按照email分组,把每个分组下所有文档的error_codes数组合并成一个大数组:

{
  "size": 0, // 不需要返回原始文档,只看聚合结果
  "aggs": {
    "email_groups": {
      "terms": {
        "field": "email.keyword" // 注意用keyword类型做精确分组
      },
      "aggs": {
        "concat_error_codes": {
          "scripted_metric": {
            "init_script": "state.error_codes = []", // 初始化分组的状态数组
            "map_script": "state.error_codes.addAll(doc['error_codes'].values)", // 收集每个文档的error_codes
            "combine_script": "return state.error_codes", // 合并当前分片内的结果
            "reduce_script": "def merged = []; for (s in states) { merged.addAll(s); } return merged;" // 合并所有分片的结果
          }
        }
      }
    }
  }
}

脚本逻辑说明

每个脚本的作用一目了然:

  • init_script:为每个email分组创建一个空数组,用来存放后续收集到的错误码。
  • map_script:遍历当前分组下的每一篇文档,把文档里的error_codes数组所有元素添加到状态数组中。
  • combine_script:在单个分片内,把该分片收集到的数组返回,准备进行跨分片合并。
  • reduce_script:把所有分片返回的数组合并成一个最终的大数组,这就是你要的拼接结果。

返回结果示例

执行上述查询后,会得到和你期望结构一致的结果:

{
  "aggregations": {
    "email_groups": {
      "buckets": [
        {
          "key": "user@mail.com",
          "concat_error_codes": {
            "value": ["12.03","23.22","44.45","34.2","23.22","44.45"]
          }
        }
      ]
    }
  }
}

可选:给数组去重

如果需要去掉重复的错误码,只需要修改reduce_script(或combine_script),用哈希表来去重:

"reduce_script": "def merged = new HashSet(); for (s in states) { merged.addAll(s); } return merged.toArray();"

这样返回的数组就不会有重复元素了。

注意事项

  • 确保error_codes字段的类型支持脚本访问:如果是text类型,需要开启fielddata;如果是keyword类型则直接可用。
  • 如果error_codes是嵌套字段,需要调整脚本中的访问路径(比如doc['nested_field.error_codes'].values)。

内容的提问来源于stack exchange,提问作者Chili

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:49:11