Mongoose更新文档rating字段时出现Cast to Number失败错误求助
问题描述
需要实现文档rating字段的更新逻辑:将现有rating值与传入的newRating值取平均值,覆盖原字段。模型中rating定义为必填Number类型,取值范围0-5。使用findByIdAndUpdate方法时,Postman测试出现Cast to Number failed for value错误。
模型定义代码
rating: { type: Number, min: 0, max: 5, required: true, },
控制器代码
const { newRating, bookID, userName, comment } = req.body; const updateRating = await Book.findByIdAndUpdate( { _id: bookID }, { rating: { $divide: [{ $inc: { rating: Number(newRating) } }, 2] }, $inc: { numOfRatings: 1 }, }, { new: true } );
报错信息
{ "message": "Cast to Number failed for value \"{ '$divide': [ { '$inc': [Object] }, 2 ] }\" (type Object) at path \"rating\"", "stack": "CastError: Cast to Number failed for value \"{ '$divide': [ { '$inc': [Object] }, 2 ] }\" (type Object) at path \"rating\"\n at model.Query.exec (D:\\Programs\\VS Code\\Web Development\\lmsbackend\\node_modules\\mongoose\\lib\\query.js:4891:21)\n at model.Query.Query.then (D:\\Programs\\VS Code\\Web Development\\lmsbackend\\node_modules\\mongoose\\lib\\query.js:4990:15)\n at processTicksAndRejections (node:internal/process/task_queues:96:5)" }
解决方案
错误原因
写法存在两个核心问题:
$inc是独立的更新操作符,不能嵌套在$divide这类聚合表达式中使用- 直接给
rating字段赋值包含MongoDB操作符的对象,Mongoose会尝试将该对象转换为Number类型,导致类型转换失败
修正后的代码
要实现平均值更新,需要用$expr支持聚合表达式更新,通过$add和$divide组合计算平均值:
const { newRating, bookID, userName, comment } = req.body; // 提前校验newRating合法性 const parsedRating = Number(newRating); if (isNaN(parsedRating) || parsedRating < 0 || parsedRating > 5) { return res.status(400).json({ message: 'newRating必须是0-5之间的数字' }); } const updateRating = await Book.findByIdAndUpdate( bookID, { $expr: { $set: { rating: { $divide: [{ $add: ['$rating', parsedRating] }, 2] }, numOfRatings: { $add: ['$numOfRatings', 1] } } } }, { new: true, runValidators: true } );
补充说明
- 使用
$expr后,可在更新语句中引用当前文档的字段值(如$rating、$numOfRatings) - 添加
runValidators: true确保更新后的rating值符合模型定义的0-5范围校验 - 提前校验
newRating合法性,避免无效值进入更新逻辑
内容的提问来源于stack exchange,提问作者Roshan Shetty
相关产品推荐
相关产品推荐

