我在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级下来?)
答案 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/)
嵌套数组位置$运算符不能用于查询 遍历多个数组,例如遍历的查询 嵌套在其他数组中的数组,因为替换了$ 占位符是单个值。