最简聚合查单字段重复只需两步:按目标字段分组→筛出计数大于1的组;_id必须设为"$fieldname",count用{$sum:1},null值需预过滤以防误判。

直接用 $group + $match 就能定位重复值,但必须注意分组键、性能限制和 null 值干扰 —— 否则查不到真重复,或查出来就卡死。
怎么写最简聚合查单字段重复
核心就是两步:按目标字段分组 → 筛出计数大于 1 的组。不需要额外排序或 limit,除非你明确要 Top N。
-
_id必须设为"$fieldName",不能漏掉$符号,否则会当成字面量字符串分组 -
count: { $sum: 1 }是标准写法,别写成{ $count: {} }(那是 MongoDB 5.0+ 新操作符,不兼容旧版) - 如果字段可能为
null或缺失,$group仍会把它们归到同一个_id: null组里 —— 这算不算“重复”得看业务定义,必要时加$match: { fieldName: { $exists: true, $ne: null } }预过滤
示例(查 users 集合中重复的 email):
db.users.aggregate([
{ $group: { _id: "$email", count: { $sum: 1 } } },
{ $match: { count: { $gt: 1 } } }
])
查多字段组合重复要改 _id 结构
当重复判定依赖多个字段(比如 name + phone 联合唯一),_id 必须是对象,不能拼字符串 —— 否则会因类型/顺序/空格导致误判。
- 正确写法:
_id: { name: "$name", phone: "$phone" },MongoDB 自动按字段名和值结构比对 - 错误写法:
_id: { $concat: ["$name", "$phone"] },一旦某个字段为null,整个结果变null,所有记录被塞进同一组 - 如果字段有大小写混用或前后空格问题,得先在
$group前加$addFields标准化,例如:{ $addFields: { cleanName: { $trim: { input: "$name" } } } }
示例(查 orders 中相同 user_id + product_id 的重复下单):
db.orders.aggregate([
{ $group: { _id: { user_id: "$user_id", product_id: "$product_id" }, count: { $sum: 1 } } },
{ $match: { count: { $gt: 1 } } }
])
大数据量下不加 allowDiskUse: true 会直接报错
MongoDB 聚合默认内存上限 100MB,一旦分组键基数高(比如千万级用户查 email),$group 阶段极易触发 errmsg: "Sort exceeded memory limit..." 或直接中断。
- 必须显式传
{ allowDiskUse: true }选项,让引擎把中间结果暂存磁盘 - 该选项只在
aggregate()方法调用时生效,不是 pipeline 阶段;Node.js 驱动里要写在第二个参数位置,例如:collection.aggregate(pipeline, { allowDiskUse: true }) - 开启后查询变慢是正常的,但至少能跑完;若仍超时,考虑加
$match先缩小数据范围(如限定created_at时间窗)
GridFS 文件内容重复要单独处理 filemd5
GridFS 的 fs.files 集合里,filemd5 字段是驱动写入时自动生成的 MD5,可作初筛依据,但不能全信。
- 必须先排除
filemd5: null的记录,因为非标准写入(如直插文档)不会设该字段,参与分组会导致误合并 - 聚合时用
$match: { filemd5: { $ne: null } }开头,再$group,否则null值全挤进一组,count虚高 - 查出重复
filemd5后,不能直接删 —— 得用bucket.openDownloadStream()读出原始内容,重新计算 MD5 比对,否则可能删掉内容实际不同的文件
示例(查 GridFS 中真正可能重复的文件):
db.fs.files.aggregate([
{ $match: { filemd5: { $ne: null } } },
{ $group: { _id: "$filemd5", count: { $sum: 1 }, ids: { $push: "$_id" } } },
{ $match: { count: { $gt: 1 } } }
])
真正麻烦的从来不是写出聚合语句,而是确认「哪些值该被视作重复」——字段是否允许为空、大小写是否敏感、null 算不算一个有效值、多字段组合时要不要标准化。这些判断没对齐,查出来的结果再快也没用。











