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 中的嵌入式数组
MongoDB - Mongoose 查询 findOneAndUpdate() 不更新/复制数据库
MongoDB - Mongoose 查询 findOneAndUpdate() 不更新/复制数据库