如何将auditdata_history集合数据快速迁移至auditdata且保留原有数据
高效迁移MongoDB备份集合数据到目标集合的方案
针对你需要将auditdata_history的260万条唯一记录迁移到已有80万条数据的auditdata集合且不覆盖目标数据的需求,提供以下两种高效方案:
方案一:使用聚合$merge阶段(推荐,高性能批量合并)
MongoDB 4.2及以上版本支持$merge聚合阶段,它可以将聚合结果合并到目标集合中,不会清空目标集合,还能灵活处理重复数据。
执行命令
db.auditdata_history.aggregate([ // 可选:如果需要过滤迁移的记录,在这里添加$match条件,否则匹配所有数据 { $match: {} }, { $merge: { into: "auditdata", // 目标集合名称 on: "_id", // 用于判断记录唯一性的字段(通常用_id,可根据你的业务唯一键修改) whenMatched: "keepExisting", // 遇到重复记录时的处理:保留目标集合的现有数据 whenNotMatched: "insert" // 无匹配记录时插入新数据 } } ])
参数说明
on:指定唯一标识字段,确保不会重复插入相同记录,若你的业务用其他唯一键(如audit_id),替换即可。whenMatched:可选值还有replace(替换目标记录)、merge(合并字段)、fail(抛出错误),根据你的需求选择。whenNotMatched:除了insert,还可以选discard(丢弃不插入),这里我们需要插入所有备份数据,所以用insert。
方案二:批量插入(兼容低版本MongoDB)
如果你的MongoDB版本低于4.2,无法使用$merge,可以用批量插入替代逐条forEach,性能远高于单条插入。
执行脚本
const batchSize = 1000; // 每次批量插入的记录数,可根据你的服务器性能调整(建议1000-5000) let skipCount = 0; while (true) { // 分批查询备份集合的数据 const batchDocs = db.auditdata_history.find().skip(skipCount).limit(batchSize).toArray(); if (batchDocs.length === 0) { print("数据迁移完成"); break; } // 批量插入到目标集合,ordered:false表示遇到错误不中断,继续插入剩余数据 db.auditdata.insertMany(batchDocs, { ordered: false }); skipCount += batchSize; print(`已完成 ${skipCount} 条记录迁移`); }
注意事项
ordered: false:如果备份集合中存在与目标集合重复的记录,开启此参数会跳过重复错误,继续插入其他数据;如果确定无重复,可以省略此参数,提升插入速度。- 批量大小:避免设置过大导致单条命令超过MongoDB的16MB限制,根据单条记录大小调整。
前置操作建议
- 迁移前务必备份
auditdata集合,防止意外:db.auditdata.copyTo("auditdata_pre_migration_backup") - 建议在业务低峰期执行迁移操作,避免影响线上业务性能。
内容的提问来源于stack exchange,提问作者Abcd Efgh
相关产品推荐
相关产品推荐

