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

Elasticsearch统计嵌套数组内层元素总数量(含重复)实现方法

你当前得到的计数不符合预期,是因为Elasticsearch对普通Object类型的数组默认做拍平存储,不会保留数组内各个对象的边界。比如你第二个文档中inner数组有两个John和一个James,存储时inner.name会被处理为去重后的["John", "James"],普通terms聚合统计的是包含该值的父文档数量,两个父文档都包含John,所以计数为2。

以下是两个适配你需求的可选方案:

方案1:使用Nested类型(改动最小)

首先调整索引mapping,将inner字段设置为nested类型,该类型会保留数组内每个对象的独立边界:

PUT 你的索引名/_mapping
{
  "properties": {
    "inner": {
      "type": "nested"
    }
  }
}

重新写入数据后,使用nested聚合搭配terms即可得到正确计数:

{
  "size": 0,
  "aggs": {
    "inner_docs": {
      "nested": {
        "path": "inner"
      },
      "aggs": {
        "name_count": {
          "terms": {
            "field": "inner.name.keyword",
            "size": 10
          }
        }
      }
    }
  }
}

返回结果中aggregations.inner_docs.name_count.buckets就是你需要的统计值。现在7.3以上版本的Kibana已经原生支持nested字段的聚合操作,在Lens、常规可视化面板中都可以直接选择nested字段做统计,兼容问题已经不大。

方案2:平铺文档结构(Kibana兼容性最优)

如果完全不想接触nested的使用限制,可以直接在数据写入时将每个inner对象拆分为独立的顶层文档,结构调整为:

[
  {"profile": "123", "name": "John"},
  {"profile": "456", "name": "John"},
  {"profile": "456", "name": "John"},
  {"profile": "456", "name": "James"}
]

调整后你原来的聚合语句直接修改字段为name即可得到正确结果,且所有Kibana功能都可以直接使用,没有任何兼容问题,是维护成本最低的方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:57:01