我的文档结构大致类似于以下内容:
{
"_id": "theIdOfThisObject",
"subdoc": {
"array": [
[
{
"parameters": {},
"winner": null,
"participants": [
"Person1",
"Person2"
]
},
{
"parameters": {},
"winner": null,
"participants": [
"Person3",
"Person4"
]
}
],
[]
]
},
}
我完全试图替换嵌套数组中的一个子文档。我不需要搜索它 - 我知道确切的位置。
例如,我正在尝试将第一个子文档替换为
"parameters": {"frog":20},
"winner": "Person1",
"participants": [
"Person1",
"Person2"
]
我们会说它被保存为一个名为 newObject
.
我希望以下代码可以工作(Model
是一个真正的猫鼬模型):
Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, function(err,doc){
console.log('doc is returned, but nothing is updated')
});
我不知道发生了什么以及为什么这不起作用。有人有什么建议吗?我已经使用MongoDB的本机节点驱动程序很长时间(3年),但是Mongoose对我来说相当新。
编辑 - 根据注释请求添加架构
架构非常简单。如下所示:
var Schema = new mongoose.Schema({
subdoc: {
array: [{}]
}
});
那里还有其他字段,但在这种情况下,这是唯一重要的字段。我的理解是,让模式具有[{}]
意味着将有一个任何类型的 JSON 排列数组。架构还允许我最初设置有问题的子文档 - 它只是出于任何原因不允许我更新它。
我已经解决了这个问题。显然,当将Mixed
模式类型(与 {}
相同)与 Mongoose 一起使用时,更新对象中的子字段是一个 2 步过程。你不能只使用findByIdAndUpdate()
.
您必须首先使用 fineById()
,在回调中获取文档,对相关文档运行markModified()
(传入子文档的路径),最后保存该文档。代码如下:
Model.findById('theIdOfThisObject', function(err,doc){
//update the proper subdocument
doc.subdoc.array[0][0] = newObject;
//then mark it as modified and save it
doc.markModified('brackets.rounds');
//save the model
doc.save(callback);
});
也许这里有两件事。
首先,在你的 sheme 中,我建议你使用
var Schema = new mongoose.Schema({
subdoc: {
array: [{type: Schema.Types.Mixed}]
}});
这样它就被正确地定义为可以有任何东西。
或者可能缺少的第二件事。如果现有条目不存在,则必须设置 upsert :true 选项,新条目也会入。
Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, {upsert : true},console.log);
我遇到了同样的问题,我可以确认,这一行是修复的:
doc.markModified('brackets.rounds');