MongoDB不更新双嵌套数组中的子文档(使用Mongoose FindByIdAndUpdate) - 已知的确切位置

thi*_*ami 2 mongoose mongodb node.js mongodb-query node-mongodb-native

我的文档结构与以下内容大致相似:

{
    "_id": "theIdOfThisObject",
    "subdoc": {
        "array": [
            [
                {
                    "parameters": {},
                    "winner": null,
                    "participants": [
                        "Person1",
                        "Person2"
                    ]
                },
                {
                    "parameters": {},
                    "winner": null,
                    "participants": [
                        "Person3",
                        "Person4"
                    ]
                }
            ],
            []
        ]
    },
}
Run Code Online (Sandbox Code Playgroud)

我完全试图替换嵌套数组中的一个子文档.我不需要搜索它 - 我知道确切的位置.

例如,我试图用第一个子文档替换

                    "parameters": {"frog":20},
                    "winner": "Person1",
                    "participants": [
                        "Person1",
                        "Person2"
                    ]
Run Code Online (Sandbox Code Playgroud)

我们会说它被保存为一个叫做的对象newObject.

我希望以下代码可以工作(并且Model是一个真正的Mongoose模型):

Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, function(err,doc){
  console.log('doc is returned, but nothing is updated')
});
Run Code Online (Sandbox Code Playgroud)

我不知道发生了什么,为什么这不起作用.有人有什么建议吗?我一直在使用MongoDB的本机节点驱动程序很长一段时间(3年),但是Mongoose对我来说还是比较新的.

编辑 - 根据评论请求添加模式

架构非常简单.看起来如下:

var Schema   = new mongoose.Schema({
    subdoc: {
        array: [{}]
    }
});
Run Code Online (Sandbox Code Playgroud)

那里还有其他领域,但在这种情况下,这是唯一重要的领域.我的理解是,使用Schema有一种[{}]方法可以存在任何类型的JSON排列.Schema还允许我最初设置有问题的子文档 - 它不会让我因任何原因更新它.

thi*_*ami 5

我已经弄明白了这个问题.显然,当使用与Mongoose 的MixedSchema类型({}与之相同)时,更新对象中的子字段是一个两步过程.你不能只是使用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);
});
Run Code Online (Sandbox Code Playgroud)