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

Mongoose更新totalOrders时出现NaN类型转换失败错误求助

问题描述

执行以下代码时触发类型错误:

const fullOrdersForService = service.totalOrders
const updatedFullOrdersForService = fullOrdersForService + 1
const updateService = await Service.findOneAndUpdate({_id:serviceId}, { totalOrders: updatedFullOrdersForService },{new:true})

已确认service.totalOrders为Number类型且非NaN,Schema定义如下:

totalOrders:{
  type:Number,
  required:true,
  default:0
}

错误信息:

messageFormat: undefined,
stringValue: '"NaN"',
kind: 'Number',
value: NaN,
path: 'totalOrders',
reason: AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
assert.ok(!isNaN(val))
原因分析
  • 竞态条件导致的并发冲突:先读取文档再修改更新的模式存在漏洞,当多个请求同时操作同一文档时,部分请求可能读取到旧值,计算后更新时触发Mongoose的类型验证异常。
  • 模型中间件干扰:若Mongoose模型配置了pre-update或pre-save钩子,钩子内的代码可能意外修改totalOrders的值,使其变为NaN。
  • 隐性类型转换异常:尽管已确认当前service.totalOrders为Number,但若文档曾被手动修改、数据迁移时出现类型不兼容,可能导致更新值在传输或验证环节被转为NaN。
解决办法
  • 使用原子更新(推荐):利用MongoDB的$inc操作符直接在数据库层面完成递增,彻底避免竞态问题,同时保证操作原子性:
    const updateService = await Service.findOneAndUpdate(
      { _id: serviceId },
      { $inc: { totalOrders: 1 } },
      { new: true }
    );
    
  • 排查模型中间件:检查模型的pre钩子函数,确保没有代码在更新流程中非法修改totalOrders字段。
  • 添加防御性校验:在计算更新值时增加类型和有效性校验,避免无效值传入更新操作:
    const fullOrdersForService = service.totalOrders;
    const updatedFullOrdersForService = typeof fullOrdersForService === 'number' && !isNaN(fullOrdersForService) 
      ? fullOrdersForService + 1 
      : 1; // 可根据业务逻辑调整默认值
    
    const updateService = await Service.findOneAndUpdate(
      { _id: serviceId },
      { totalOrders: updatedFullOrdersForService },
      { new: true }
    );
    

内容的提问来源于stack exchange,提问作者Nisandu Athsara

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:57:22