聚合与深分页
用途:用 ES 做统计与分组时避免“内存爆、数字不准”
聚合三类
「聚合三类」小节链接| 类型 | 例子 | 说明 |
|---|---|---|
| 指标(Metrics) | avg、sum、max、stats、percentiles、cardinality |
计算数值 |
| 桶(Bucket) | terms、date_histogram、range、histogram、filter、nested |
分组 |
| 管道(Pipeline) | derivative、cumulative_sum、bucket_sort、moving_avg |
在桶结果之上二次计算 |
精度陷阱
「精度陷阱」小节链接terms聚合是近似的:每个分片先取自己的size × shard_size再归并,跨分片长尾统计可能偏差。用shard_size调优,或明确“这是 Top-N 近似”。cardinality是 HLL 估算:误差随基数增长(默认precision_threshold3000,上限 40000)。要求精确去重时用其他方案(数据库、位图、分组累加)。percentiles基于 t-digest 近似:tdigest.compression控制精度与内存。- 缺失值与空桶:
date_histogram的min_doc_count: 0+extended_bounds补齐时间轴;missing参数处理字段缺失。
高基数聚合怎么办
「高基数聚合怎么办」小节链接按用户 ID、订单号这类高基数字段分组会消耗大量内存与 CPU:
| 需求 | 方案 |
|---|---|
| Top-N 大类别 | terms + 合理 size,配合 include 过滤 |
| 全量分组统计 | 交给数仓/OLAP(ClickHouse、Doris 类),ES 只做检索与轻量聚合 |
| 精确去重计数 | 数据库或位图结构(RoaringBitmap 类) |
| 多维下钻 | 预聚合汇总表,或列式 OLAP 引擎 |
经验边界:ES 适合“检索 + 有限维度聚合”,不适合当 OLAP 引擎用。
嵌套与父子聚合
「嵌套与父子聚合」小节链接nested聚合:对数组内对象保持关联统计(如“订单行按品类聚合”)。reverse_nested:从子文档回到父文档维度统计。- 子文档聚合代价高,设计阶段就要判断是否真的需要 nested(很多场景可拆成独立索引 + 关联查询)。
性能抓手
「性能抓手」小节链接- 聚合字段必须有
doc_values(列式正排),否则无法聚合。 - 先
filter缩小文档集再聚合。 - 控制桶数量:嵌套桶乘积会爆炸(
date_histogram × terms × range)。 - 用
execution_hint: map/composite分页聚合处理大结果集(composite支持游标翻页)。 - 避免在 text 字段上开
fielddata。 - 大聚合走独立节点/线程池,避免影响在线查询。
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 把 cardinality 当精确 UV | 明确它是估算,或换方案 |
| terms 聚合 size=10000 取全量 | 内存与延迟风险,用 composite 分页或离线计算 |
| 用 ES 做复杂多表关联分析 | 关联能力弱,交给 OLAP/数仓 |
| 聚合与检索混在一个慢查询里 | 拆分:检索列表 + 单独聚合请求(可缓存) |
| 忽略时区 | date_histogram 显式 time_zone,或统一 UTC 存储 |
延伸阅读
「延伸阅读」小节链接- Elasticsearch 官方文档:Aggregations、composite、Precision and recall of terms aggregator
- 《Elasticsearch 权威指南》聚合章节