章节摘要:聚合管道(Aggregation Pipeline)是把文档流经一系列阶段逐级加工的分析框架,核心阶段有 match、group、sort、project 等。本章从一次聚合内存超限事故与一次慢聚合事故讲起,覆盖管道概念、常用阶段与优化手法。读完本章,你能写出既正确又不拖垮集群的分析查询。
金句:管道的每一段都在为下一段减负——顺序错了,就是把整条河的水抽进一根吸管。
4.1 先把每个"加工段"的语义与限制搞清,4.2 再把它们排成省资源的顺序——懂零件再懂装配。两节共用一个事实:管道没有全局优化器,你写的顺序就是执行计划。SQL 时代交给数据库的重排工作,在这里是写代码的人的责任,本章两起事故都是这个责任缺位的直接后果。
阶段语义(4.1) ──► 顺序与优化(4.2) │ │ $match/$group 尽早过滤 · 索引利用 · 分桶
一个务实的练习建议:拿自己项目里最慢的一条统计 SQL 或接口,用 explain 逐阶段标注输出文档数,找出膨胀位置。十有八九,瓶颈就藏在 unwind 或 group 之前那个没被提前的 $match 里。
离开本章前逐条自查:能否默写 match、group、unwind、lookup 各自的输入输出形态;能否说出 group 与 sort 两个阶段默认 100MB 内存红线的来历与 allowDiskUse 的代价;能否解释为什么 match 放在 unwind 之前通常更省、而 project 提前为什么可能弄丢下游要用的字段;能否给一条慢聚合画出逐阶段文档数变化,标出膨胀点;能否判断一个报表场景该用实时聚合、merge 预聚合还是干脆给个独立从库。答不上来的条目,回到对应小节的事故档案重看定位过程。
本章内容在团队内部转述时常被简化走样,这里把两个高频误传钉死。误传一:"allowDiskUse 一开就安全了"——它只是把溢出写到磁盘,磁盘 IO 争抢同样能拖垮同机的其他负载,档案里的主从切换正是缓存挤占的连锁反应,磁盘化只是把病房换了一间。误传二:"聚合比在应用层循环查询快"——对少量文档成立,对千万级全表聚合,应用层分页拉取反而能控制节奏。结论永远跟着测量走,这是第 10 章会反复回到的主题。
前置:第 2 章查询语法、第 3 章索引。延伸:聚合是第 10 章慢查询分析的常客,也是把分析负载从应用层收回数据库层的主力工具。