MongoDB迁移:将users的ObjectId作为外键写入po1集合失败排查
MongoDB迁移脚本未写入关联ObjectId字段排查
根因定位
脚本无效果的直接原因是查询条件存在笔误:
- 你在
db.po1.find()的查询参数中,将匹配字段错写为"owner:"(字段名末尾多了一个冒号),MongoDB会将这个带冒号的字符串识别为不存在的字段,查询永远返回空游标,内层遍历po1文档的逻辑完全不会执行,自然不会写入user_id字段。 - 脚本无报错是MongoDB的正常行为:查询不存在的字段不会抛出语法/运行时错误,仅会返回空结果集,因此整个脚本可以跑完但没有任何实际数据变更。
修正后的基础脚本
删除查询条件里字段名末尾多余的冒号即可,修正后代码:
db.users.find().forEach(function (user) { var cursor = db.po1.find({"owner": user.ID}); cursor.forEach(function(property) { property.user_id = user._id; db.po1.save(property); }); });
大数据量场景优化方案
你提到po1集合单用户数据体量较大,逐条save()的写入性能很差,建议改用updateMany做批量更新,执行效率会有明显提升,也能减少长时遍历带来的库级锁占用:
db.users.find().forEach(function (user) { db.po1.updateMany( {"owner": user.ID}, {$set: {"user_id": user._id}} ); });
配套Mongoose配置提示
脚本执行完成后,在po1集合对应的Mongoose Schema中做如下配置即可正常使用关联查询,不需要采用文档嵌入方案:
- 将
user_id字段类型定义为mongoose.Schema.Types.ObjectId - 给该字段添加
ref属性,值对应用户集合的模型名称
内容的提问来源于stack exchange,提问作者peter
相关产品推荐
相关产品推荐

