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

MongoDB使用mongoose时upsert:true插入结果不符合预期如何解决?

问题根因

  1. 更新参数语法错误:你在更新体中把playerStatsObjForDB外层套了一层大括号,等价于{ playerStatsObjForDB: playerStatsObjForDB },实际是尝试写入一个名为playerStatsObjForDB的嵌套字段,而非将该对象内的playerName、points等字段写入文档根层级。由于你的Schema未定义该嵌套字段,Mongoose会默认忽略未声明字段,最终插入的文档仅保留查询条件里的_id和默认生成的__v字段。
  2. 若语法正确但仍缺失字段,需检查Points对应的Schema是否声明了playerName、points字段,Mongoose默认不会插入Schema中未定义的字段。

解决方案

方案1:使用$set操作符更新字段(推荐,仅覆盖传入的字段,保留其他已有字段)

await Points.findOneAndUpdate(
  {
    "_id": playerStatsObjForDB._id
  }, 
  // 直接传入对象给$set,会将对象内所有字段写入文档根层级
  { $set: playerStatsObjForDB }, 
  {
    upsert: true,
    new: true // 可选配置,开启后返回更新/插入后的最新文档
  }
);

方案2:开启overwrite全量替换文档(适合需要完全覆盖旧文档所有字段的场景)

await Points.findOneAndUpdate(
  {
    "_id": playerStatsObjForDB._id
  }, 
  // 直接传完整文档对象,不要额外套外层大括号
  playerStatsObjForDB, 
  {
    upsert: true,
    overwrite: true, // 开启全量替换模式
    new: true
  }
);

Schema校验

确认你的Points模型的Schema定义包含所有需要写入的字段,示例如下:

const mongoose = require('mongoose');

const pointsSchema = new mongoose.Schema({
  _id: {
    playerId: String,
    tournamentId: String,
    matchId: String
  },
  playerName: String,
  points: Number
});

const Points = mongoose.model('Points', pointsSchema);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 04:45:08