← 返回文章列表
数据库·283 次阅读

MongoDB 聚合管道:从 find 到 Aggregation

MongoDB 聚合管道:从 find 到 Aggregation

简单查询用 find 足够,但"每个分类下有多少篇已发布文章、平均阅读量多少、按排名输出"这类统计,需要聚合框架。

管道思想

Aggregation 是一条处理流水线:文档依次流过各个阶段(stage),每个阶段做一件事,输出交给下一个——和 Unix 管道、Stream 是同一种心智模型:

db.posts.aggregate([
  { $match: { status: 'PUBLISHED' } },        // 1. 先过滤(尽量前置,减少后续数据量)
  { $group: {                                  // 2. 分组
      _id: '$categoryId',
      count: { $sum: 1 },
      avgViews: { $avg: '$views' },
      titles: { $push: '$title' },
    } },
  { $sort: { count: -1 } },                    // 3. 排序
  { $limit: 10 },                              // 4. 取前 10
])

常用阶段

阶段 作用 类比 SQL
$match 条件过滤 WHERE
$group 按键分组聚合 GROUP BY
$sort / $limit / $skip 排序、分页 ORDER BY / LIMIT
$project 字段裁剪、计算新字段 SELECT
$lookup 关联另一集合(左外连接) LEFT JOIN
$unwind 数组拆成多行 展开数组

$lookup 示例——文章关联分类信息:

db.posts.aggregate([
  { $match: { status: 'PUBLISHED' } },
  { $lookup: {
      from: 'categories',
      localField: 'categoryId',
      foreignField: '_id',
      as: 'category',
    } },
  { $unwind: '$category' }, // 数组结果展开为对象
])

常用表达式

$sum、$avg、$max、$min、$push(收集成数组)、$addToSet(去重收集);字段引用加 $ 前缀('$views')。

性能注意

  • $match、$limit 尽量前置,先缩小数据集
  • $group 无法走索引,海量数据成本高,考虑预聚合(定时任务把统计结果写入新集合,读多算少)
  • $lookup 有关联成本,确认外集合的 foreignField 有索引
  • explain('executionStats') 查看各阶段处理文档数

聚合管道把复杂统计以声明式的流水线表达,比手写 map-reduce 直观得多,是 MongoDB 进阶必学的一章。

看到这里了?如果这篇文章帮到过你

请我喝瓶可乐就好 🥤

收款码

评论0 条

还没有评论,来抢沙发~

发表评论

评论需审核后显示

© 2026 许冬博客 · 专注 JS 技术分享

·RSS 订阅·Powered by Nuxt 4