MongoDB如何删除重复文档并仅保留同cusId下最新插入的记录?
1. 获取MongoDB文档创建时间
MongoDB默认生成的_id字段为ObjectId类型,本身嵌入了文档创建时间戳,无需额外新增创建时间字段,两种常用获取方式如下:
- 单条文档提取创建时间:直接调用ObjectId的
getTimestamp()方法即可,示例:
// 替换为对应文档的_id ObjectId("6122ca5df5ee9d5974c6e886").getTimestamp()
- 聚合查询批量提取创建时间:使用
$toDate操作符将_id转换为时间格式,示例:
{ $addFields: { createTime: { $toDate: "$_id" } } }
另外由于ObjectId按插入时间递增生成,数值越大的_id对应插入时间越晚,你原有逻辑中用$max取同分组最大_id判断最晚插入文档的思路是完全正确的。
2. 删除cusId重复文档、仅保留最晚插入记录
你编写的聚合已经可以正确筛选出需要删除的重复文档_id,后续可以直接基于该逻辑完成删除,推荐两种常用实现方案:
方案一:先查待删ID再批量删除(适合大数据量集合,性能更高)
// 1. 执行聚合拿到所有待删除的重复文档_id数组 const toDeleteIds = db.你的集合名.aggregate([ { $group: { _id: "$cusId", mongoIds: { $addToSet: "$_id" }, count: { $sum: 1 } } }, { $match: { count: { $gt: 1 } } }, { $project: { duplicates: { $filter: { input: "$mongoIds", as: "mongoId", cond: { $lt: ["$$mongoId", { $max: "$mongoIds" }] } } } } }, // 扁平化处理,提取所有待删除_id { $unwind: "$duplicates" }, { $replaceRoot: { newRoot: "$duplicates" } } ]).toArray() // 2. 批量删除重复文档 db.你的集合名.deleteMany({ _id: { $in: toDeleteIds } })
方案二:直接调用deleteMany删除(适合小数据量集合,写法更简单)
db.你的集合名.deleteMany({ $expr: { $lt: [ "$_id", // 查找同cusId分组下最晚插入的文档_id db.你的集合名.findOne({ cusId: "$cusId" }, { sort: { _id: -1 }, limit: 1 })._id ] } })
注意:执行删除操作前,建议先把
deleteMany替换为find验证待删除的文档是否符合预期,避免误删数据。
内容的提问来源于stack exchange,提问作者Nick Smith
相关产品推荐
相关产品推荐

