如何使用Mongoose为已存在的Fruit、Person文档建立关联
问题原因
- 异步执行时序错误:
Person.update()是异步操作,原代码在查询回调外直接关闭数据库连接,会导致更新操作还没执行完成,连接就被提前关闭,更新失效。 - 查询未触发执行:Mongoose 中如果没有给更新方法传入回调、也没有调用
.exec()或者用await等待,只会创建查询实例,不会真正向数据库发起更新请求。 - 方法兼容问题:
update()方法在新版 Mongoose 中已废弃,推荐使用语义更明确的updateOne()方法更新单条文档。
正确实现代码
回调写法
Fruit.find({name: "Mango"}, function(err, mangoResult){ if(err) { console.log(err); return mongoose.connection.close(); } Person.updateOne({name: "John"}, {favouriteFruit: mangoResult[0]}, function(updateErr, updateRes) { if(updateErr) { console.log(updateErr); } else { console.log(`更新完成,匹配文档数:${updateRes.matchedCount},修改文档数:${updateRes.modifiedCount}`); } // 所有操作完成后再关闭连接 mongoose.connection.close(); }); });
async/await 写法(更推荐)
async function bindUserFruit() { try { const mango = await Fruit.findOne({name: "Mango"}); const updateRes = await Person.updateOne({name: "John"}, {favouriteFruit: mango}); console.log("更新成功", updateRes); } catch (err) { console.log("操作出错:", err); } finally { await mongoose.connection.close(); } } bindUserFruit();
额外优化建议
当前设计是将水果文档作为嵌入子文档存储到Person表中,后续如果Fruit表的Mango文档属性更新,John的favouriteFruit字段不会自动同步。如果需要数据联动,可以将favouriteFruit字段改为引用类型:
const personSchema = new mongoose.Schema({ name: String, age: Number, favouriteFruit: { type: mongoose.Schema.Types.ObjectId, ref: "Fruit" } });
后续查询Person数据时调用 .populate("favouriteFruit") 即可自动关联取出完整的水果文档。
内容的提问来源于stack exchange,提问作者Sanjay Bakshi
相关产品推荐
相关产品推荐

