我有一个令人困惑的奇怪问题。我有一个模特:
var Model = new Schema({
name: String,
variations: Array
});
变体条目如下所示:
[ {code: '', price: '' }, {code: '', price: '' }]
我需要添加一个新字段 - 比如“color”。所以我这样做是为了批量更新:
Model.find().exec(function(err, products) {
if (!err) {
products.forEach(function(p) {
for(var i = p.variations.length - 1; i >= 0; i--) {
p.variations[i]['color'] = 'red';
// This shows all existing variations
// with the new color feed - correct
console.log(p.variations[i]);
}
p.save(function(err) {
if (!err) {
console.log("Success");
} else {
console.log(err);
}
});
});
}
});
然而,“颜色”字段未设置 - 如果我再次检查并注释掉p.variations[i]['color'] = 'red';
行,则它不会显示。我似乎无法弄清楚为什么这样做。我有一个正确触发的onSave事件,所以它正在保存。我也没有检查变体结构 - 即没有代码只允许代码和价格。我显然错过了一些东西,但几个小时后我的想法就用完了。
答案 0 :(得分:29)
当您修改Array
这样的无类型variations
字段的内容时,您需要通过调用修改后的文档上的markModified(path)
或后续内容来通知Mongoose您已更改其值save()
来电不会保存。 See docs
for(var i = p.variations.length - 1; i >=0; i--) {
p.variations[i]['color'] = 'red';
}
p.markModified('variations');
p.save(function(err) { ...
答案 1 :(得分:3)
您必须使用 set 功能更改属性。其背后的原因是,猫鼬必须将字段标记为已修改才能保存到数据库中。
for(var i = p.variations.length - 1; i >=0; i--) {
p.variations[i].set({"color":"red", "code":"herr"});
// or
p.variations[i].set("color":"red");
p.variations[i].set("code":"herr");
}
另一种方法是以旧的方式更改字段的值,而不用设置器,然后手动将其标记为已修改:p.markModified('variations');
在我看来,你应该总是使用setter,因为它更具可读性。您只需传递一个包含参数中所有更改的json对象,它就会安全地更新您 想要更改的字段。