$group的_id必须为表达式而非字符串字面量,因_id用于动态提取字段值分组;写成"gender"会将所有文档归入同一组,正确写法是"$gender"或{dept:"$dept",year:"$year"};数组需先$unwind才能统计,否则$sum等操作无效。

直接用 $group 就能统计分组数据,但多数人卡在 _id 写错、漏掉汇总表达式,或没意识到数组字段必须先 $unwind。
为什么 $group 的 _id 不能写成字符串字面量?
_id 不是字段名占位符,而是表达式——写成 "gender" 就真会按字符串 "gender" 分一组;正确写法是 "$gender",表示取文档中 gender 字段的值作为分组键。
- 错误:
{ _id: "gender", count: { $sum: 1 } }→ 所有文档被归到同一个_id: "gender"组里 - 正确:
{ _id: "$gender", count: { $sum: 1 } }→ 按实际字段值(如0或1)分组 - 想按多个字段组合分组?用对象:
{ _id: { dept: "$dept", year: "$year" } }
统计嵌套数组里的元素数量,为什么 $sum 不管用?
因为 $group 对数组字段不做自动展开。比如学生文档里有个 atndnc 数组存考勤记录,直接 $sum: "$atndnc" 会报错或返回空——MongoDB 不允许对数组直接求和。
一款AI视频创作工具,主要用于蛙蛙写作辅助AI写文,帮助获取创意灵感,提供拆书、小说转剧本、视频生成等功能,是一款功能全面的AI智能写作工具,适合需要提升相关任务效率的用户。
- 必须先用
$unwind拆开:{ $unwind: "$atndnc" } - 再在
$group中按rollno分组,用$sum: 1算总次数,$sum: { $cond: [ { $eq: ["$atndnc.status", "present"] }, 1, 0 ] }算出勤次数 - 注意:
$unwind遇到空数组或缺失字段默认报错,加preserveNullAndEmptyArrays: true参数可跳过
如何避免 $group 后丢失原始字段?
$group 输出只保留 _id 和显式声明的汇总字段,其他字段全部丢弃。如果还想带出姓名、班级等信息,得在 $group 前用 $project 提前提取,或在 $group 里用 $first/$last 保一个值。
- 常见做法:
{ _id: "$rollno", name: { $first: "$name" }, total: { $sum: 1 } } - 但要注意:
$first不保证顺序,除非前面加了$sort - 若需完整子文档(如整个
student对象),用$push: "$$ROOT",但慎用——容易撑爆内存
真正麻烦的不是语法,而是分组逻辑和数据形态不匹配:数组没 $unwind、字段路径写错层级、条件判断漏写 $cond 包裹——这些地方一错,结果就静默偏差,很难 debug。










