You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 12:47:38