在MongoDB中更新嵌套数组内的嵌套对象

8 浏览
0 Comments

在MongoDB中更新嵌套数组内的嵌套对象

我有一个类似以下代码的文档:

{
    id : 100,
    heros:[
        {
           nickname : "test",
           spells : [
             {spell_id : 61, level : 1},
             {spell_id : 1, level : 2}
           ]
        }
    ]
}

我无法使用heros中昵称为"test"的英雄内的spells中的spell_id : 1设置level : 3。我尝试了以下查询:

db.test.update({"heros.nickname":"test", "heros.spells.spell_id":1}, 
{$set:{"heros.spells.$.level":3}});

我看到的错误是:

无法使用字符串字段名[spells]附加到数组中

感谢帮助。

0
0 Comments

更新MongoDB中数组内嵌套数组中的嵌入对象的问题出现的原因是,MongoDB目前还没有提供在更新语句中放置函数的能力。这个问题已经被提出并记录在JIRA上,但尚未得到解决。

解决方法是使用以下代码:

db.test.find({"heros.nickname":"test"}).forEach(function(x) {  
    bool match = false;
    for (i=0 ; i< x.heros[0].spells.length ; i++) {
        if (x.heros[0].spells[i].spell_id == 1) 
        {
            x.heros[0].spells[i].level = 3;
            match = true;
        }
    }
    if (match === true) db.test.update( { id: x.id }, x );
});

然而,这段代码存在一个问题,就是在查找和更新之间存在一个时间窗口,如果在该时间窗口内有其他查询在数组的相同索引处添加或删除了嵌入文档,那么更新操作将覆盖先前添加/删除的文档。

希望这篇文章对你有所帮助。

0
0 Comments

问题原因:在MongoDB中,我们只能使用$符号来更新单层级的数组。而在这个问题中,heros是一个嵌套的数组,而且每个hero还有一个spells的数组。

解决方法:如果我们知道数组的索引,可以在更新的时候使用明确的索引。例如:

> db.test.update({"heros.nickname":"test", "heros.spells.spell_id":1}, {$set:{"heros.0.spells.1.level":3}});

以上代码中,我们通过指定明确的索引来更新数组中嵌套数组的元素。

0