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

MongoDB执行$push/$inc操作时报错updateOne不是函数如何解决?

报错根本原因
  • findOne() 执行后返回的是匹配查询条件的普通文档对象,属于纯JSON数据结构,既不是MongoDB的集合实例,也不是Mongoose的Model实例。只有集合/Model对象才拥有updateOne这类数据库更新方法,直接在文档对象上调用该方法自然会触发类型错误。
  • 原代码中查询bot的findOne没有加await关键字,返回的是Pending状态的Promise对象,即便解决了user的调用问题,后续调用bot.updateOne也会触发同类报错。
正确写法规范
  1. 更新操作的调用主体必须是集合对象/Model对象,不能直接在findOne返回的文档对象上调用更新方法,需要在更新方法的第一个参数传入筛选条件定位要更新的文档,你修正后的写法就符合该要求。
  2. 所有异步数据库操作都必须加await关键字,包括findOne、updateOne、findOneAndUpdate等,否则拿到的是Promise对象,无法获取正确的返回数据,也会导致后续逻辑报错。你修正后的代码中findOneAndUpdate也建议加上await,方便捕获异常、确认更新结果。
  3. 如果需要先读取文档做逻辑校验再更新,有两种通用实现方案:
    • 原子化更新方案(推荐):校验逻辑完成后直接调用集合的更新方法,使用$push、$inc这类原子操作符执行更新,数据库层面单次操作原子性更高,可避免并发场景下的数据覆盖问题,示例如下:
    // 校验逻辑省略
    await users.findOneAndUpdate({"token": data.user}, {$push: {"likedBots": data.id}})
    await bots.findOneAndUpdate({"id":data.bot}, {$inc: {"like": 1}})
    
    • 文档修改后保存方案(仅适用于Mongoose Model场景):拿到文档对象后直接修改对应属性,再调用save()方法提交修改:
    let user = await UserModel.findOne({"token": data.user})
    if(user && user.likedBots) {
      user.likedBots.push(data.id)
      await user.save()
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 18:15:02