【问题标题】:Update embedded object inside array inside array in MongoDB更新MongoDB中数组内的嵌入对象
【发布时间】:2012-05-05 20:45:20
【问题描述】:

我有类似的文件

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

我不能 $set 拼写 level : 3spell_id : 1 里面 spells 里面 heros 昵称“测试。我试过这个查询:

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

我看到的错误是

无法使用字符串字段名称 [spells] 附加到数组 感谢您的帮助。

【问题讨论】:

    标签: mongodb mongodb-query


    【解决方案1】:

    您只能将$ 位置运算符用于单级数组。在您的情况下,您有一个嵌套数组(heros 是一个数组,其中每个英雄都有一个 spells 数组)。

    如果您知道数组的索引,则可以在进行更新时使用显式索引,例如:

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

    【讨论】:

      【解决方案2】:

      试试这样的:

      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 );
      });
      

      显然有人开了一张票以添加在更新子句中放置函数的能力,但尚未解决:https://jira.mongodb.org/browse/SERVER-458

      【讨论】:

      • 您的代码不起作用。我认为 x 将是所有文件,不是吗?
      • @DenisErmolin 哎呀......是的,那是错误的。我又拍了一张(见更新)。 x 是文档,对,所以我认为您应该能够通过 id 属性对其进行更新。
      • x.spells 引用法术,但英雄数组中的法术
      • 对我来说效果很好,只需要将变量从:bool match = false 改为 $match = false,然后使用 $match 来引用即可。
      • @McGarnagle 但此代码在查找和更新之间不会是原子的,假设您在索引 1 处找到 spell_id == 1,同时在索引 1 处添加/删除了一些其他查询,现在将会发生的是,当您的查询将在 mongo 中更新时,它会将更新后的值放在索引 1 处,这将覆盖之前在索引 1 处添加/删除的文档。
      猜你喜欢
      • 2015-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      相关资源
      最近更新 更多