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

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)"
}
解决方案

错误原因

写法存在两个核心问题:

  1. $inc是独立的更新操作符,不能嵌套在$divide这类聚合表达式中使用
  2. 直接给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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 22:55:29