更新MongoDb中的深层记录

时间:2014-02-27 07:48:16

标签: mongodb mongodb-query

我在MongoDb中有此记录,并且正在使用本机API:

{
    "_children" : {
        "addressesR" : [
            {
                "id" : ObjectId("530eea01071bd1a53065c1a6"),
                "personId" : ObjectId("530eea01071bd1a53065c1a4"),
                "street" : "ivermey",
                "city" : "perth",
                "_children" : {
                }
            },
            {
                "_children" : {
                    "configId" : {
                        "a" : {
                            "_children" : [
                                {
                                    "b" : 10
                                },
                                {
                                    "b" : 20
                                }
                            ]
                        }
                    }
                },
                "city" : "perth",
                "configId" : ObjectId("530eea01071bd1a53065c1a3"),
                "id" : ObjectId("530eea01071bd1a53065c1a5"),
                "personId" : ObjectId("530eea01071bd1a53065c1a4"),
                "street" : "bitton"
            }
        ],
    }
}

我需要在一个查询中更新嵌套'b'到30。 我可以找到记录:

db.peopleR.find( { '_children.addressesR._children.configId.a._children.b': 20 } );

但我很难找到更新该特定值的方法。

我在尝试:

db.peopleR.update( { '_children.addressesR._children.configId.a._children.b': 20 }, { $set: { '_children.addressesR.$._children.configId.a.$._children.b': 30 }   }  )

但我得到了:

Cannot apply the positional operator without a corresponding query field containing an array.

现在,考虑到其他约束,我绝对需要更新只是'b',有没有办法让我这样做?或者,两次使用$操作数是不可能的? (也就是说,我只能更新一个对象的内部部分,如果它只有1级下来?)

2 个答案:

答案 0 :(得分:3)

问题是您无法使用$运算符在数组中的嵌套级别显示匹配。最重要的是,你只能指定一次。

正如documentation所述,$ 匹配第一个元素。那不是意味着如果您的查询有多个匹配项,那么只会选择第一个匹配项,这也意味着 第一个匹配的数组将使用的位置。这意味着这样的事情也行不通:

{ $set: { '_children.addressesR.1._children.configId.a._children.$.b': 30 } 

因为这会错误地匹配index 1值并更新您不期望的项目。

如果您可以更新整个数组,那么以下内容将起作用:

{ $set: {"_children.addressesR.$._children.configId.a._children": [ { b: 10}, { b: 30} ] } }

就像我说的那样,因为index匹配第一个数组。

但是考虑到你拥有的结构,看起来最好的选择是将顶级数组更改为子文档。除非实际上有理由成为一个数组,而不是现在看来的两个混合文档类型。

答案 1 :(得分:0)

您的查询有问题。第二个$应该在_children之后。但即使在那之后出现相同的错误。所以看来你是对的。我尝试给出第二部分的确切数组位置并且它有效。

db.peopleR.update( { '_children.addressesR._children.configId.a._children.b': 20 }, { $set: { '_children.addressesR.$._children.configId.a._children.0.b': 30 }   }  )

似乎你需要知道至少一个阵列位置。

编辑:来自mongodb文档(http://docs.mongodb.org/manual/reference/operator/update/positional/

  

嵌套数组位置$运算符不能用于查询   遍历多个数组,例如遍历的查询   嵌套在其他数组中的数组,因为替换了$   占位符是单个值。