【问题标题】:Mongoose not updating array in mongodbMongoose 不更新 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, }, ], })

标签: node.js mongodb mongoose


【解决方案1】:

我相信数组没有被保存的原因是guildScores 字段的类型是Array。在documentation of the Array schema type 中,它表示仅指定Array 等同于MixedThe 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
猜你喜欢
  • 2020-04-18
  • 1970-01-01
  • 1970-01-01
  • 2019-06-10
  • 2015-01-31
  • 2015-10-04
  • 2015-09-19
  • 2023-01-18
  • 1970-01-01
相关资源
最近更新 更多