MongoDB 4.2.21:按最低Score及更早CreationDate筛选重复文档
MongoDB 4.2.21 按规则清理重复文档
需求说明
按DocumentId字段识别重复文档,同一DocumentId分组内:
- 保留所有Score值最低的文档;
- 删除Score高于组内最低分的文档;
- 若需在Score相同的最低分文档中仅保留创建时间最早的,可调整后续聚合条件。
实现步骤
MongoDB 4.2不支持直接在删除操作中嵌入聚合逻辑,需分两步完成:先通过聚合查询定位待删除的文档ID,再执行批量删除。
1. 聚合查询获取待删除文档ID
// 替换yourCollectionName为你的集合名称 db.yourCollectionName.aggregate([ // 按DocumentId分组,计算每组的最低Score,同时收集组内所有文档的ID、Score信息 { $group: { _id: "$DocumentId", minScore: { $min: "$Score" }, docs: { $push: { _id: "$_id", Score: "$Score" } } } }, // 展开每组的文档列表 { $unwind: "$docs" }, // 筛选出Score高于组内最低分的文档(这些是要删除的) { $match: { "docs.Score": { $gt: "$minScore" } } }, // 仅提取待删除的文档ID { $project: { _id: "$docs._id" } } ])
2. 执行批量删除
将聚合结果转为ID数组后,执行删除:
// 获取待删除ID列表 const toDeleteIds = db.yourCollectionName.aggregate([/* 上述聚合管道 */]).toArray().map(item => item._id); // 批量删除文档 db.yourCollectionName.deleteMany({ _id: { $in: toDeleteIds } });
可选:相同最低分仅保留最早创建的文档
若需求改为“Score相同时,仅保留CreationDate最早的文档,删除其余同Score的最低分文档”,可修改聚合管道如下:
db.yourCollectionName.aggregate([ { $group: { _id: "$DocumentId", minScore: { $min: "$Score" }, earliestDate: { $min: "$CreationDate" }, docs: { $push: { _id: "$_id", Score: "$Score", CreationDate: "$CreationDate" } } } }, { $unwind: "$docs" }, { $match: { $or: [ { "docs.Score": { $gt: "$minScore" } }, { $and: [ { "docs.Score": { $eq: "$minScore" } }, { "docs.CreationDate": { $gt: "$earliestDate" } } ] } ] } }, { $project: { _id: "$docs._id" } } ])
示例验证
针对提供的示例数据:
DocumentId: "05240423067"组最低Score为2,因此删除Score=5的文档(_id: UUID("c77c72de-edd8-4576-a72c-983cf93a0f31")),保留两个Score=2的文档;DocumentId: "88313825863"组最低Score为1,因此删除Score=2的文档(_id: UUID("f1a063a5-f9dd-4998-b6aa-df2071dd8677")),保留Score=1的文档。
执行后结果与预期完全一致。
内容的提问来源于stack exchange,提问作者DValdir Martins
相关产品推荐
相关产品推荐

