Mongoose使用lean查询含非模型属性对象后无法保存的问题求助
解决Mongoose lean()查询后无法保存更新的问题
我来帮你梳理下问题所在和解决办法:
首先,你遇到的核心问题是:lean()方法返回的是普通JavaScript对象,不再是Mongoose的Document实例,所以它没有save()方法;而你用Order.update({_id:order._id},{order})没生效,是因为更新的写法不对。
方案1:去掉lean(),直接用Mongoose文档实例操作
既然你已经在模型里设置了strict: false,Mongoose是允许保存模型中未定义的属性的,完全不需要用lean()。直接查询出文档实例,修改后调用save()即可:
let order = await Order.findOne({_id: req.body.id}).populate({path: 'o_s', match: {removed: false}}); // 直接修改属性,包括模型未定义的字段 order.someExistingField = '更新后的值'; order.newUndefinedField = '新增的未定义属性值'; // 保存修改 await order.save(); return res.json({status: true, message: 'Order Updated', order: order});
这种方式最直观,还能利用Mongoose的中间件(比如pre/post save钩子),是优先推荐的方案。
方案2:如果必须用lean(),用正确的更新方法
如果因为某些场景你一定要用lean()获取普通对象,那更新时要使用Mongoose提供的findByIdAndUpdate或updateOne方法,而不是旧的update语法:
let order = await Order.findOne({_id: req.body.id}).populate({path: 'o_s', match: {removed: false}}).lean(); // 修改普通对象的属性 order.someField = '新值'; order.undefinedField = '新增属性'; // 使用findByIdAndUpdate更新,{new: true}会返回更新后的文档 const updatedOrder = await Order.findByIdAndUpdate(req.body.id, order, {new: true}); return res.json({status: true, message: 'Order Updated', order: updatedOrder});
如果你只想更新部分字段,用$set更高效(避免替换整个文档):
await Order.updateOne( {_id: req.body.id}, { $set: { someField: '新值', undefinedField: '新增属性' } } ); // 如果需要返回更新后的文档,用findById查询一次或者用findOneAndUpdate const updatedOrder = await Order.findById(req.body.id); return res.json({status: true, message: 'Order Updated', order: updatedOrder});
为什么你之前的update写法没生效?
你写的Order.update({_id:order._id},{order})有两个问题:
{order}这种写法等价于{order: order},这不是正确的更新格式——Mongoose会认为你要给文档添加一个名为order的字段,值是你的order对象,而不是替换或更新文档内容。- 旧的
update方法默认不返回更新后的文档,而且在新版本Mongoose中已经被updateOne/updateMany替代,不再推荐使用。
内容的提问来源于stack exchange,提问作者JenuRudan
相关产品推荐
相关产品推荐

