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

Elasticsearch聚合问题:如何排除travel数组中active=false的城市?

Elasticsearch嵌套数组聚合:仅统计active=true的城市

问题背景

现有文档数据结构如下:

[
    {
        "name": "Scott",
        "origin": "London",
        "travel": [
            {
                "active": false,
                "city": "Berlin",
                "visited": "2020-02-01"
            },
            {
                "active": true,
                "city": "Prague",
                "visited": "2020-02-15"
            }
        ]
    },
    {
        "name": "Lilly",
        "origin": "London",
        "travel": [
            {
                "active": true,
                "city": "Scotland",
                "visited": "2020-02-01"
            }
        ]
    }
]

要完成的聚合需求:

  1. 先按顶层origin字段分桶
  2. 统计每个城市的访问人数,只算travel数组里active=true的条目

之前用普通filter聚合时,只要文档里有一个travel.active=true的元素,就会把整个文档的travel数组都纳入统计,导致结果里还包含了active=false的Berlin,不符合要求。

期望的聚合输出:

{
  "aggregations": {
    "origin": {
      "buckets": [
        {
          "key": "London",
          "buckets": [
            {
              "key": "travel_nested",
              "doc_count": 2,
              "buckets": [
                {
                  "key": "active_travel_filter",
                  "doc_count": 2,
                  "buckets": [
                    {
                      "key": "Scotland",
                      "doc_count": 1
                    },
                    {
                      "key": "Prague",
                      "doc_count": 1
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

解决方法

普通filter聚合没法针对嵌套数组的单个元素做精准过滤,必须用嵌套聚合(nested aggregation),把数组里的每个对象当作独立单元处理。

正确的聚合配置代码:

{
  "from": 0,
  "aggs": {
    "origin": {
      "terms": {
        "field": "origin"
      },
      "aggs": {
        "travel_nested": {
          "nested": {
            "path": "travel"
          },
          "aggs": {
            "active_travel_filter": {
              "filter": {
                "term": {
                  "travel.active": true
                }
              },
              "aggs": {
                "city": {
                  "terms": {
                    "field": "travel.city.keyword"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

核心要点

  • 用nested聚合指定path: "travel",让Elasticsearch把数组中的每个对象独立看待,而不是把整个数组当成一个字段。
  • 先进入嵌套上下文,再用filter筛选active=true的元素,最后对符合条件的城市进行分桶统计。
  • 如果travel.city是文本类型,必须用travel.city.keyword进行分桶,否则会按分词后的词汇聚合,结果不符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:15:48