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

如何在Elasticsearch中对列表内对象进行唯一结果聚合

问题:Elasticsearch中按关联的key-value对聚合

当前映射

"custom_metadata": {
  "properties": {
    "key": {
      "type": "keyword"
    },
    "value": {
      "type": "keyword"
    }
  }
}

已导入的数据

文档1

"custom_metadata": [
    {
      "value": "NPL",
      "key": "schema"
    },
    {
      "value": "SAPERP",
      "key": "system"
    }
  ]

文档2

"custom_metadata": [
    {
      "value": "trial",
      "key": "schema"
    },
    {
      "value": "Oracle",
      "key": "system"
    }
  ]

预期聚合结果

希望按每个key分组,得到对应的value集合,示例格式如下:

"schema": [
  {"value": "NPL"},
  { "value": "trial"}
],
"system":[
  {"value": "SAPERP"},
  { "value": "Oracle"}
]

已尝试的聚合及问题

尝试过以下嵌套聚合:

"custom_metadata_key": {
  "terms": {
    "field": "custom_metadata.key"
  },
  "aggregations": {
    "custom_metadata_value": {
      "terms": {
        "field": "custom_metadata.value"
      }
    }
  }
}

但结果中每个key的分组里会包含所有value,而非对应关联的value,例如:

{
  "key" : "schema",
  "doc_count" : 2,
  "custom_metadata_value" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count" : 0,
    "buckets" : [
      { "key" : "Oracle", "doc_count" : 2 },
      { "key" : "NPL", "doc_count" : 1 },
      { "key" : "SAPERP", "doc_count" : 1 },
      { "key" : "trial", "doc_count" : 1 }
    ]
  }
}

解决方案

出现这个问题的核心原因是:默认的object类型会将数组中的对象扁平化存储,导致key和value失去关联关系。需要将custom_metadata字段改为nested类型,并配合nested聚合实现关联查询。

1. 修改字段映射为nested类型

更新后的映射如下:

"custom_metadata": {
  "type": "nested",  // 标记为nested类型
  "properties": {
    "key": {
      "type": "keyword"
    },
    "value": {
      "type": "keyword"
    }
  }
}

注意:修改映射后需要重新导入数据,否则旧数据不会生效。

2. 使用nested聚合查询

正确的聚合查询语句:

{
  "size": 0,  // 不需要返回原始文档,只取聚合结果
  "aggs": {
    "nested_metadata": {
      "nested": {
        "path": "custom_metadata"  // 指定nested字段的路径
      },
      "aggs": {
        "group_by_key": {
          "terms": {
            "field": "custom_metadata.key"
          },
          "aggs": {
            "group_by_value": {
              "terms": {
                "field": "custom_metadata.value"
              }
            }
          }
        }
      }
    }
  }
}

聚合结果示例

执行上述查询后,会得到每个key对应关联value的聚合结果:

{
  "aggregations": {
    "nested_metadata": {
      "doc_count": 4,
      "group_by_key": {
        "buckets": [
          {
            "key": "schema",
            "doc_count": 2,
            "group_by_value": {
              "buckets": [
                {"key": "NPL", "doc_count": 1},
                {"key": "trial", "doc_count": 1}
              ]
            }
          },
          {
            "key": "system",
            "doc_count": 2,
            "group_by_value": {
              "buckets": [
                {"key": "SAPERP", "doc_count": 1},
                {"key": "Oracle", "doc_count": 1}
              ]
            }
          }
        ]
      }
    }
  }
}

这个结果可以直接在服务端解析成你需要的格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 11:50:44