Mongoose更新方法中this关键字无法访问模型属性的问题
解决Mongoose更新时验证器中
this无法访问完整文档属性的问题 问题原因
在使用findByIdAndUpdate这类批量更新方法时,Mongoose验证器中的this仅指向本次更新提交的字段集合,而非完整的文档实例。因此如果更新请求中没有传入stockQuantity,this.stockQuantity就会返回undefined;而创建文档时,this指向的是完整的新文档实例,所以能正常访问所有属性。
解决方案
方案一:改用findById + save()触发完整验证
这种方式会先获取完整的文档实例,修改后调用save(),此时验证器的this会指向完整的文档,能正常访问stockQuantity:
// 替换原有的findByIdAndUpdate代码 const box = await Box.findById(productId); if (!box) { // 处理文档不存在的逻辑 return res.status(404).json({ message: 'Box不存在' }); } // 将更新字段合并到文档实例 Object.assign(box, req.body); // 保存时触发完整验证,此时this指向完整文档 const updatedBox = await box.save();
方案二:在验证器中手动查询完整文档(不推荐,存在并发风险)
如果必须使用findByIdAndUpdate,可以在验证器中通过this._id查询完整的Box文档,再获取stockQuantity:
// 修改Box Schema中products的验证器 { validator: async function (products) { // 更新时this._id会存在,用于查询完整文档 const box = await Box.findById(this._id); if (!box) return false; const productIds = products.map(product => product.product); for (const pId of productIds) { const product = await Product.findById(pId); if (!product) continue; const matchingProduct = products.find(p => p.product.toString() === product._id.toString()); if (matchingProduct.quantity * box.stockQuantity > product.stockQuantity) return false; } return true; }, message: `One or more products do not have this quantity available in stock` }
注意:该方案会额外增加一次数据库查询,且如果在查询文档和验证之间,文档被其他请求修改,可能导致验证逻辑出现偏差,因此优先推荐方案一。
内容的提问来源于stack exchange,提问作者Luiz Carlos Gandra
相关产品推荐
相关产品推荐

