【问题标题】:MongoDB not updating subdocument within double-nested array (using Mongoose FindByIdAndUpdate) - EXACT POSITION KNOWNMongoDB 不更新双嵌套数组中的子文档(使用 Mongoose FindByIdAndUpdate) - 确切位置已知
【发布时间】:2014-11-26 01:37:08
【问题描述】:

我的文档结构大致类似于以下内容:

{
    "_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 是一个真正的 Mongoose 模型):

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: [{}]
    }
});

其中还有其他字段,但在这种情况下,这是唯一重要的字段。我的理解是,让 Schema 有一个 [{}] 意味着会有一个任何类型的 JSON 排列的数组。 Schema 还允许我最初设置有问题的子文档 - 它只是不允许我出于任何原因对其进行更新。

【问题讨论】:

  • 您是否检查了捕获结果并检查是否返回了匹配的文档。如果没有返回 - 你的 id 可能是错误的。
  • 另外请发布您的架构。可能是字段不匹配。
  • @BatScream - 刚刚添加了我的架构(或者更确切地说是与此问题有关的部分)。此外,我已经在检查回调的“doc”部分 - 绝对是正确的文档,只是没有更新的位。

标签: node.js mongodb mongoose mongodb-query node-mongodb-native


【解决方案1】:

我已经解决了这个问题。显然,当在 Mongoose 中使用 Mixed Schema 类型(与 {} 相同)时,更新对象内的子字段是一个两步过程。你不能只使用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);
});

【讨论】:

  • 括号和圆似乎不知道从哪里来,这是括号子文档和数组吗?
  • ...这对我来说毫无意义。不喜欢猫鼬
【解决方案2】:

这里可能有两件事。

首先,在你的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);

【讨论】:

  • 嗨@Mario - 这些都不是问题。我已经想通了 - 你可以看到我的答案:)
【解决方案3】:

我有同样的问题,我可以确认,这条线是修复:

doc.markModified('brackets.rounds');

【讨论】:

    猜你喜欢
    • 2021-10-23
    • 2021-03-26
    • 2016-11-23
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 2017-04-28
    相关资源
    最近更新 更多