cardinality 做什么
cardinality 聚合用来估算某个字段有多少个不同取值,相当于 SQL 里的去重计数。它内部使用 HyperLogLog++ 做近似计算,用很小的内存就能处理很大的基数;precision_threshold 参数越高结果越准,内存开销也随之上升。
基本信息
| 接口 | "cardinality": { "field": "user_id" } |
|---|---|
| 精度参数 | precision_threshold 默认 3000,上限 40000 |
| 精确性 | 基数低于阈值时结果通常精确,超过阈值后误差随基数上升 |
| 字段要求 | 应使用 keyword 或数值字段,text 字段需要 fielddata 才能聚合 |
| 组合用法 | 可放进 terms 分桶,统计每个桶内的去重数量 |
典型使用场景
- 统计独立用户数、独立 IP 等去重指标
- 监控看板里的去重维度,对误差不敏感时最合适
- 按分桶统计:每个地区有多少活跃用户
- 粗略估算字段基数,判断它是否适合作为聚合维度
- 验证字段基数是否足够低,为低基数编码之类的优化提供依据
常用写法
常用写法
# 全量去重用户数
GET /logs/_search
{ "size": 0, "aggs": { "unique_users": {
"cardinality": { "field": "user_id", "precision_threshold": 40000 } } } }
# 按分桶统计去重数量
GET /logs/_search
{ "size": 0, "aggs": { "by_region": { "terms": { "field": "region", "size": 10 },
"aggs": { "uv": { "cardinality": { "field": "user_id" } } } } } }
# 缺失值统一计数,避免漏算
GET /logs/_search
{ "size": 0, "aggs": { "uv": { "cardinality": { "field": "user_id", "missing": "unknown" } } } }
# 小基数时与精确计数对比,验证误差
GET /logs/_count
{ "query": { "term": { "user_id": "u1" } } }参数与取舍
| 参数 | 作用 | 注意 |
|---|---|---|
| field | 要去重统计的字段 | 字段类型不匹配会直接报错 |
| precision_threshold | 精度阈值,默认 3000 上限 40000 | 调高更准但内存占用上升 |
| missing | 给缺失字段的统一取值 | 不设置时缺失值不计入 |
| script | 用脚本动态取值 | 更灵活但开销更高 |
基数小于精度阈值时结果通常是精确的,远超阈值时误差随基数增大。监控看板场景一般够用,计费与对账类场景要先做误差验证再决定是否采用。
cardinality 先在每个分片各自估算、再合并到协调节点,分片多时误差会叠加;需要更稳定的结果时可以先按时间范围缩小数据,或对同一个查询用不同精度阈值跑两轮做交叉验证。