使用Mongoose鉴别器时,ProductsModel无法更新count字段问题
问题:Mongoose鉴别器父模型调用findByIdAndUpdate修改count字段无效果
我有手机、笔记本、耳机等多类产品,统一基于父模型ProductsModel管理,同时创建了PhoneModel等鉴别器子模型。实现按数量删除产品逻辑时,用子模型操作count字段完全正常,但用父模型ProductsModel调用findByIdAndUpdate修改该字段时,字段毫无变化,也无任何报错。
具体逻辑:根据ID查询产品→判断剩余数量→若只需部分删除,将count字段更新为原数量减去删除数量。
解决方案
1. 查询文档实例后修改保存
放弃直接使用findByIdAndUpdate,改为先查询出文档实例,修改字段后调用save()。这种方式下Mongoose会自动识别文档的鉴别器类型,确保字段更新生效:
const product = await ProductsModel.findById(productId); if (product) { const deleteCount = 2; // 需删除的数量 if (product.count >= deleteCount) { product.count -= deleteCount; await product.save(); } }
2. 在findByIdAndUpdate中指定鉴别器类型
如果坚持使用findByIdAndUpdate,需要在查询选项中指定鉴别器键(通常是__t)对应的子模型类型,让父模型明确要操作的文档类型:
// 假设鉴别器键为__t,目标子模型类型为'Phone' await ProductsModel.findByIdAndUpdate( productId, { $inc: { count: -deleteCount } }, // 用$inc直接实现减法,更高效且避免并发问题 { discriminatorKey: 'Phone', new: true } );
3. 校验父模型Schema的count字段定义
确认count字段在父模型ProductsModel的Schema中已正确定义,且未设置不可修改属性:
const productSchema = new mongoose.Schema({ count: { type: Number, default: 0, required: true, // 确保没有设置 immutable: true }, // 其他公共字段 }); const ProductsModel = mongoose.model('Product', productSchema); // 创建鉴别器子模型 const PhoneModel = ProductsModel.discriminator('Phone', new mongoose.Schema({ // 手机专属字段定义 }));
原因分析
Mongoose父模型执行findByIdAndUpdate时,默认不会自动推断文档的鉴别器类型,更新操作仅基于父模型Schema执行。即便父模型定义了count字段,也可能因未识别子模型类型导致更新未生效。而查询后保存的方式会让Mongoose识别文档的实际子类型,从而正确处理字段修改;使用$inc操作符不仅更高效,还能避免多请求并发更新时的数值不一致问题。
内容的提问来源于stack exchange,提问作者asd qwe
相关产品推荐
相关产品推荐

