Mongoose 不更新 mongodb 中的数组

Posted

技术标签:

【中文标题】Mongoose 不更新 mongodb 中的数组【英文标题】:Mongoose not updating array in mongodb 【发布时间】:2022-01-22 12:41:16 【问题描述】:

我尝试更新包含数组的文档的一部分。我听说这对猫鼬来说是一个很大的禁忌,但我不知道如何强制它更新数组。它在代码中正确执行(例如,它会更新本地获取的文档中的值),但是当我尝试通过await mongoUser.save() 保存它时,它不会在 mongo 中更新。

这是我的架构代码

const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema(
  id:  type: String, required: true,
  socialCreditScore:  type: Number, required: true, default: 1000 ,
  /* A+: 1050
  // A: 960 - 1050
  // B: 850 - 959
  // C: 600 - 849
  / D: 0 - 599 */
  isStaff:  type: Boolean, required: true, default: false ,
  blacklisted:  type: Boolean, required: true, default: false,
  guildScores:  type: Array, required: true, strict: false  ,
  notifyChange:  type: Boolean, required: true, default: false 
, strict: false, timestamps: true )

module.exports = mongoose.model('User', UserSchema);

这里是本地更新文档的示例


  _id: new ObjectId("61c1218ae82898e9cd7af768"),
  id: '945914953495034509',
  socialCreditScore: 2100,
  isStaff: false,
  blacklisted: false,
  # Previously: guildScores: [  id: "...", laborScore: 0  ]
  guildScores: [  id: '04503405340534545', laborScore: 2000  ],
  notifyChange: false,
  createdAt: 2021-12-21T00:36:26.871Z,
  updatedAt: 2021-12-21T00:50:27.286Z,
  __v: 0

更新用户的代码

const data = await User.find( id: message.author.id );
const mongoUser = data[0];
// ...
mongoUser.socialCreditScore += socCreditBoost;
      const guildScoreData = mongoUser.guildScores.find(guild => guild.id === message.guild.id);
      //  id, laborScore 
      guildScoreData.laborScore += salary;
      console.log(mongoUser);
      await mongoUser.save();

编辑:我注意到每次尝试更新 socialCreditScore 值时都会正确更新,但 guildScore 不会。

【问题讨论】:

请在您尝试更新文档的位置添加代码。 @MontgomeryWattss 请求确认;添加代码 @WilliamFaircloth 你能检查const guildScoreData = mongoUser.guildScores.find(guild => guild.id === message.guild.id); 是否给你带来任何价值吗?我想问题可能出在这里。您正在尝试将 guild.id 与可能是字符串的 message.guild.id 进行比较,后者是一个 mongo objectId。如果这没有返回数据,请尝试使用guild.id.toString() === message.guild.id @HimanshuShubham guild.id 不是mongo objectid,可以在console.log(guildScoreData) 返回的以下代码中观察到自我解释的解释:``` id: '921069049289523260',laborScore: 0 ` `` 哦,好的,你可以试试下面的代码,只是想检查一下是否有效User.updateMany( id: message.author.id, , $inc: "guildScores.$[guild].laborScore": salary, "socialCreditScore": socCreditBoost , arrayFilters: [ "guild.id": message.guild.id, , ], ) 【参考方案1】:

我相信数组没有被保存的原因是guildScores 字段的类型是Array。在documentation of the Array schema type 中,它表示仅指定Array 等同于Mixed。 The documentation for the Mixed schema type 状态:

由于 Mixed 是一种无模式类型,您可以将值更改为您喜欢的任何其他值,但 Mongoose 失去了自动检测和保存这些更改的能力。要告诉 Mongoose Mixed 类型的值发生了变化,您需要调用 doc.markModified(path),将路径传递给刚刚更改的 Mixed 类型。

为避免这些副作用,可以使用子文档路径。

person.anything =  x: [3, 4,  y: "changed" ] ;
person.markModified('anything');
person.save(); // Mongoose will save changes to `anything`.

在你的情况下,mongoUser.markModified('guildScores') 可能会成功。

或者,您也可以使用 Mongoose 的 findOneAndUpdate 方法在一次操作中查找和更新文档(我假设您每个 id 只有一个文档)。它可能看起来像这样:

await User.findOneAndUpdate(
     id: message.author.id, 'guildScores.id': message.guild.id ,
     $inc:  socialCreditScore: socCreditBoost, "guildScores.$.laborScore": salary 
)

【讨论】:

这行得通,我在保存之前添加了该行并运行了代码。感谢 yoru 的支持,如果您想提供有关此主题的任何上下文文档,我将不胜感激。 不客气。我查看了 Mongoose documentation 以查找有关 Mongoose 如何处理 Array 类型的信息,特别是 Schema Types page。可能值得研究subdocuments。

以上是关于Mongoose 不更新 mongodb 中的数组的主要内容,如果未能解决你的问题,请参考以下文章

过滤和更新 mongodb mongoose 中的嵌入式数组

使用mongoose在mongoDB中更新数组的数组

MongoDB - Mongoose 查询 findOneAndUpdate() 不更新/复制数据库

MongoDB - Mongoose 查询 findOneAndUpdate() 不更新/复制数据库

如何在 mongodb/mongoose 的嵌套数组中检查是不是存在并更新对象?

使用 mongoose 在 mongoDb 中更新数组内的对象 [重复]