$group(分组聚合)
最后更新:2026-10-09
$group(分组聚合)
$group 按指定字段(_id)将文档分组,并对每组应用累加器表达式($sum/$avg/$max 等)计算聚合值。它是聚合管道中功能最强的阶段,等价于 SQL 的 GROUP BY。_id 可以是字段路径("$field")或复合表达式,决定分组键。
| 分类 | 核心阶段 |
|---|---|
| MongoDB 版本 | 1.0+ |
| 示例语言 | mongosh (Shell) |
📝 语法
{ $group: { _id: <分组键>, <字段>: { <累加器>: <表达式> }, ... } }
▶ 示例
请在本地安装的 mongosh 中执行以下命令(需已启动 mongod):
// $group:按 status 分组统计数量与总额
db.orders.aggregate([
{ $group: { _id: "$status", count: { $sum: 1 }, total: { $sum: "$amount" } } }
])
运行结果:
{ "_id": "A", "count": 2, "total": 380 }
{ "_id": "B", "count": 1, "total": 130 }
📌 注意事项
- _id 不可省略,可为 null(把所有文档归为一组)
- $group 输出的字段只能是累加器或 _id 表达式,原始字段需通过 $first/$last 等取回
- $group 会打散原始文档顺序,后续如需排序要重新 $sort
🏷️ 相关标签
💡 相关案例
聚合管道进阶:复杂表达式与转换
聚合管道入门:aggregate方法与基础阶段
实战:博客评论系统CRUD
Change Streams:实时变更监听
$facet + $bucket + 文本/地理空间搜索
$lookup与多集合关联
📚 相关教程
❓ 常见问题
Q$group 和 SQL 的 GROUP BY 完全等价吗?
A核心等价,但 $group 更灵活:_id 可以是任意表达式(不只是列名),且不能直接 SELECT 非聚合列(需用 $first/$push 等取回)。
Q$group 的 _id 必须指定吗?
A必须。_id 定义分组键,可以是一个字段、表达式或复合对象;传 null 会把全部文档聚为一组做全局聚合。
Q$group 输出字段的顺序稳定吗?
AMongoDB 不保证 $group 输出文档的排序,分组顺序也不稳定。需要固定顺序时在 $group 后加 $sort 阶段。