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

Elasticsearch按geo.city分组统计去重user_id问题排查

解决Elasticsearch按嵌套字段分组统计非嵌套字段去重计数问题

问题场景

索引结构片段:

...
user_id => [
    type => keyword
],
geo => [
    type => nested
    city => [
       type => keyword
    ]
    ...
]
...

需求是按geo.city分组,统计每个城市对应的去重user_id数量,对应SQL逻辑:

select
    geo.city as user_city, count(distinct user_id) as users
from 
    `table`
group by
    user_city
order by
    users desc

尝试了以下聚合查询,但distinct_users的统计结果始终为0:

'aggs' => [
    'nested_geo' => [
        'nested' => [
             'path' => 'geo',
         ],
         'aggs' => [
              'group_by_city' => [
                   'terms' => [
                        'field' => 'geo.city',
                   ],
                   'aggs' => [
                        'distinct_users' => [
                             'cardinality' => [
                                  'field' => 'user_id',
                             ],
                        ],
                   ],
              ],
         ],
     ],
 ],

问题原因

进入nested聚合的上下文后,只能访问嵌套文档(即geo字段下的内容)中的字段,而user_id是根级别字段,不属于嵌套文档的一部分,因此在嵌套上下文里直接统计user_id会找不到数据,返回0。

解决方案

使用reverse_nested聚合回到根文档上下文,之后再对user_id进行去重计数(cardinality)。修改后的聚合查询如下:

'aggs' => [
    'nested_geo' => [
        'nested' => [
             'path' => 'geo',
         ],
         'aggs' => [
              'group_by_city' => [
                   'terms' => [
                        'field' => 'geo.city',
                        'order' => ['distinct_users' => 'desc'] // 按用户数倒序,匹配SQL逻辑
                   ],
                   'aggs' => [
                        'back_to_root' => [
                             'reverse_nested' => [], // 回到根文档上下文
                             'aggs' => [
                                  'distinct_users' => [
                                       'cardinality' => [
                                            'field' => 'user_id'
                                       ]
                                  ]
                             ]
                        ]
                   ],
              ],
         ],
     ],
 ],

说明

  1. reverse_nested聚合的作用是退出嵌套文档上下文,回到包含该嵌套字段的根文档中,此时就能正常访问根级别字段user_id。
  2. 在terms聚合中添加order参数,实现按用户数倒序排列,与原SQL的order by users desc逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 20:43:10