MongoDB - 如何更新嵌套数组/对象中的值?

时间:2016-05-07 23:04:56

标签: mongodb

我的Mongo集合中有一个文档,其中包含一个具有以下结构的字段:

"_id" : "F7WNvjwnFZZ7HoKSF",
"process" : [
    {
        "process_id" : "wTGqVk5By32mpXadZ", 
        "stages" : [
            {
                "stage_id" : "D6Huk89DGFsd29ds7",
                "completed" : "N"
            }, 
            {
                "stage_id" : "Msd390vekn09nvL23",
                "completed" : "N"
            }
        ]
    }
]

我需要更新completed的值stage_id等于'D6Huk89DGFsd29ds7' - 更新查询将不知道阶段数组中哪个对象stage_id的这个值在。。

我该怎么做?

2 个答案:

答案 0 :(得分:1)

由于你的对象中有嵌套数组,这有点棘手,我不确定这个问题是否可以通过一个更新查询来解决。

但是,如果您碰巧知道第一个数组中匹配对象的索引,在您的情况process[0]中,您可以编写更新查询,如。

db.collection.update(
    {"process.stages.stage_id":"D6Huk89DGFsd29ds7"},
    {$set:{"process.0.stages.$.completed":"Y"}}
);

上面的查询将与您的测试用例完美配合。同样,仍有可能在根级别拥有多个对象,并且无法保证匹配对象始终位于0索引处。

如果您有多个process子元素并且对象的匹配索引不为零,则上面提出的解决方案将失败。

但是,您可以通过客户端编程实现目标。即查找匹配文档,在客户端修改并用新内容替换整个文档。

由于这种方法非常有效,我建议您考虑更改文档结构以避免嵌套。创建另一个集合并在那里移动process数组的内容。

答案 1 :(得分:0)

最后,我删除了外部process块,以便process_idstages位于文档的根目录中 - 使更新过程更容易使用:

MyColl.update(
    {
        _id: 'F7WNvjwnFZZ7HoKSF',
        "stages.stage_id": 'D6Huk89DGFsd29ds7'
    },
    {
        $set: {"stages.$.completed": 'Y'}
    }
);