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

时间:2021-06-26 21:26:14

I have a document structure that's roughly similar to the following:

我的文档结构大致类似如下:

{
    "_id": "theIdOfThisObject",
    "subdoc": {
        "array": [
            [
                {
                    "parameters": {},
                    "winner": null,
                    "participants": [
                        "Person1",
                        "Person2"
                    ]
                },
                {
                    "parameters": {},
                    "winner": null,
                    "participants": [
                        "Person3",
                        "Person4"
                    ]
                }
            ],
            []
        ]
    },
}

I am entirely trying to replace one of the subdocuments within the nested array. I do not need to search for it - i know the exact position.

我正在尝试替换嵌套数组中的一个子文档。我不需要找它——我知道确切的位置。

For example, I am trying to replace the first subdocument with

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

                    "parameters": {"frog":20},
                    "winner": "Person1",
                    "participants": [
                        "Person1",
                        "Person2"
                    ]

which we'll say is saved as an object called newObject.

它被保存为一个名为newObject的对象。

I expect the following code to work (and Model is a real Mongoose Model):

我期望下面的代码能够工作(模型是一个真正的Mongoose模型):

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

I have no idea what is going on and why this isn't working. Does anybody have any suggestions? I have been using MongoDB's native node driver for a very long time (3 years), but Mongoose is fairly new to me.

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

EDIT - adding schema as per comment request

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

The schema is pretty straightforward. looks as follows:

模式非常简单。看起来如下:

var Schema   = new mongoose.Schema({
    subdoc: {
        array: [{}]
    }
});

There's other fields in there, but this is the only one that matters in this case. My understanding is that having the Schema have a [{}] means that there will be an array of any kind of JSON arrangement. The Schema also lets me initially set the subdocument in question - it just doesn't let me update it for whatever reason.

这里还有其他字段,但这是这里唯一重要的字段。我的理解是,拥有模式有一个[{}]意味着将有一个任何类型的JSON排列的数组。该模式还允许我在最初设置子文档——它只是不允许我以任何理由更新它。

3 个解决方案

#1


4  

I have figured out the issue. Apparently when using the Mixed Schema type, (which is the same as {}) with Mongoose, updating a subfield within the object is a 2 step process. You can't just use findByIdAndUpdate().

我已经解决了这个问题。显然,当使用与Mongoose相同的混合模式类型(与{}相同)时,更新对象中的子字段需要两个步骤。不能只使用findByIdAndUpdate()。

You must first use fineById(), grab the document in the callback, run markModified() on the document in question (passing in the path to the subdocument), and then finally save said document. Here's the code:

您必须首先使用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);
});

#2


0  

Maybe there are two things here.

也许这里有两件事。

First, in your sheme i recommend that you use

首先,我建议你在你的音素中使用

var Schema   = new mongoose.Schema({
subdoc: {
    array: [{type: Schema.Types.Mixed}]
}});

so that it is rightly defined as there can be anything.

这样它就被正确地定义为可以有任何东西。

Or the second thing that might could be missing. If the existing entry doesn't exist you have to set the option upsert :true that new entrys will also get inserted.

或者第二件可能会丢失的事情。如果现有条目不存在,您必须设置选项upsert:true,新条目也将被插入。

Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, {upsert : true},console.log);

#3


0  

I had the same problem and I can confirm, this line was the fix:

我也有同样的问题,我可以确认,这行是修正:

doc.markModified('brackets.rounds');

#1


4  

I have figured out the issue. Apparently when using the Mixed Schema type, (which is the same as {}) with Mongoose, updating a subfield within the object is a 2 step process. You can't just use findByIdAndUpdate().

我已经解决了这个问题。显然,当使用与Mongoose相同的混合模式类型(与{}相同)时,更新对象中的子字段需要两个步骤。不能只使用findByIdAndUpdate()。

You must first use fineById(), grab the document in the callback, run markModified() on the document in question (passing in the path to the subdocument), and then finally save said document. Here's the code:

您必须首先使用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);
});

#2


0  

Maybe there are two things here.

也许这里有两件事。

First, in your sheme i recommend that you use

首先,我建议你在你的音素中使用

var Schema   = new mongoose.Schema({
subdoc: {
    array: [{type: Schema.Types.Mixed}]
}});

so that it is rightly defined as there can be anything.

这样它就被正确地定义为可以有任何东西。

Or the second thing that might could be missing. If the existing entry doesn't exist you have to set the option upsert :true that new entrys will also get inserted.

或者第二件可能会丢失的事情。如果现有条目不存在,您必须设置选项upsert:true,新条目也将被插入。

Model.findByIdAndUpdate('theIdOfThisObject',{$set: {'subdoc.array.0.0':newObject}}, {upsert : true},console.log);

#3


0  

I had the same problem and I can confirm, this line was the fix:

我也有同样的问题,我可以确认,这行是修正:

doc.markModified('brackets.rounds');