在MongoDb中更新深层记录

4

我在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”,有没有办法让我这样做?或者说,$操作符不能使用两次吗?(也就是说,如果只有一级下的对象,则只能更新其内部部分?)


截至MongoDB 2.4版本,没有定位运算符可以进行嵌套匹配和更新超过一层的操作。在MongoDB问题跟踪器中,相关的问题是SERVER-831,请关注并投票支持。 - Stennie
2个回答

3
问题在于你不能使用 $ 运算符在数组的嵌套级别中显示匹配。最重要的是,你只能指定一次。
根据文档所述,$ 仅会匹配找到的第一个元素。这不仅意味着如果你的查询有多个匹配项,那么只会选择第一个,而且还意味着只有第一个匹配的数组位置将被使用。这意味着像这样的东西也行不通:
{ $set: { '_children.addressesR.1._children.configId.a._children.$.b': 30 } 

如果这样做,会错误地匹配 index1 值,并更新您没有预期的项目。

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

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

正如我所说的那样,因为index匹配的是第一个数组。

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


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/

嵌套数组 定位符$运算符不能用于查询遍历超过一个数组的情况,例如遍历嵌套在其他数组中的数组的查询,因为$占位符的替换是单个值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接