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

Elasticsearch如何获取字段的唯一键值对(非聚合计数结果)

嘿,刚好处理过类似的需求,我来给你详细说说怎么在Elasticsearch里获取多字段的唯一键值对组合,完全匹配你要的去重效果!

方法1:多字段Terms聚合(小数据量首选)

如果你的数据量不算特别大,直接用脚本把两个字段拼接成唯一标识,再做Terms聚合就能拿到结果。

先看查询DSL:

{
  "size": 0,  // 不需要返回原始文档,只关注聚合结果
  "aggs": {
    "unique_name_city_pairs": {
      "terms": {
        "script": {
          "source": "doc['name.keyword'].value + '|' + doc['city.keyword'].value"
        },
        "size": 10000  // 按需调整,确保能覆盖所有唯一组合
      }
    }
  }
}

这里用|作为分隔符把name和city的精确值(必须用keyword类型,不然会分词出错)拼接成唯一字符串,每个聚合桶就对应一组唯一的name+city组合。之后你只需要把桶的key拆分回键值对就行,比如把james|chicago拆成{"name": "james", "city": "chicago"}。

方法2:Composite聚合(大数据量场景必备)

如果数据量很大,Terms聚合的size设太大容易引发内存问题,这时候用Composite聚合更稳妥——它支持分页获取所有唯一组合,不会一次性加载大量数据。

查询DSL如下:

{
  "size": 0,
  "aggs": {
    "unique_pairs": {
      "composite": {
        "sources": [
          { "name": { "terms": { "field": "name.keyword" } } },
          { "city": { "terms": { "field": "city.keyword" } } }
        ]
      }
    }
  }
}

这个聚合会直接返回结构化的键值对,每个桶的key就是你要的去重结果,比如:

"buckets": [
  { "key": { "name": "james", "city": "chicago" }, "doc_count": 2 },
  { "key": { "name": "james", "city": "san francisco" }, "doc_count": 1 },
  { "key": { "name": "Mike", "city": "chicago" }, "doc_count": 1 },
  ...
]

你只需要提取每个桶里的key部分就好。如果需要获取全部组合,可以通过after参数分页查询,直到返回的buckets为空。

重要提示
  • 一定要确保name和city字段有对应的keyword类型映射!text类型会被分词,根本没法做精确的聚合匹配,如果没有的话得先调整字段映射。
  • 要是不需要聚合返回的doc_count(也就是每个组合出现的次数),直接忽略这个字段就行,我们要的就是key里的内容。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 22:27:51