假设我在阵列中获得了嵌入文档的以下文档:
{
"name" : "test",
"children" : [
{
"name" : "child1",
"children" : [
{
"name" : "sub1",
"children" : [
{"name" : "c1"},
{"name" : "c2"},
{"name" : "c3"},
{"name" : "c4"},
{"name" : "c5"}
]
}
]
},
{
"name" : "child2",
"children" : [
{
"name" : "sub2",
"children" : [
{"name" : "c1"},
{"name" : "c2"},
{"name" : "c3"},
{"name" : "c4"}
]
},
{
"name" : "sub3",
"children" : [
{"name" : "c1"},
{"name" : "c2"},
{"name" : "c3"},
{"name" : "c4"}
]
},
{
"name" : "sub4",
"children" : [
{"name" : "c1"},
{"name" : "c2"},
{"name" : "c3"},
{"name" : "c4"}
]
}
]
}
]
}
我们可以看到,test
有两个孩子:child1
和child2
,而孩子有自己的孩子,如sub1
,sub2
,{ {1}},sub3
等,等等。
目前,我必须更新一些儿童内容,但我遇到了以下两个问题:
sub4
,当我意外地输入错字时(名称findOne()
应为child1
):child2
我仍然可以正确地获取文档'test',但由于我输错了db.collection_name.findOne({
'name': 'test',
'children.name': 'child1', // -> should be `child2`
'children.children.name': 'sub2'
})
实际上在sub2
下,而不是child2
,那么我怎么能得到正确的{{ {1}}结果?
child1
,当我尝试更新findOne()
的数组updateOne()
时,它运行良好(代码也类似于官方文档中的示例): child1
但是,当我还尝试更新children
的数组(db.collection_name.updateOne({
'name': 'test',
'children.name': 'child1' // locate child1
}, {
'$set':{'children.$.children':[some other content]}
})
下)时,同样的方式失败,错误为sub3
,这里的代码有问题:
child2
如果有人可以提前帮助解决这两个问题,我会非常感激,谢谢!
答案 0 :(得分:1)
对于第一个问题,您可以使用$elemMatch
查找确切的元素。
db.collection_name.findOne({
'name':'test',
children:{
$elemMatch:{
'name':'child2',
'children.name':'sub2'
}
}
})
我猜mongo不支持多个嵌套数组更新,但如果您知道子阵列位置,则可以使用此方法。
db.collection_name.updateOne({
'name':'test',
children:{
$elemMatch:{
'name':'child2',
'children.name':'sub3'
}
}
}
, {
$set: {"children.$.children.1.children" :
[
{"name" : "c1"},
{"name" : "c2"},
{"name" : "c3"},
{"name" : "c4"}
]
}
}
)
答案 1 :(得分:1)
第一个问题:查询数组时查询返回结果,因为匹配是针对数组的所有元素进行评估,即第一个匹配'children.name': 'child1'
匹配第一个元素,第二个'children.children.name': 'sub2'
匹配第二个元素。
使用$elemMatch(query)将两个条件匹配到同一个数组元素。
db.collection_name.findOne({
'name': 'test',
'children':{$elemMatch:{'name': 'child2', 'children.name': 'sub2'}}
})
第二个问题:Mongodb 3.6现在通过arrayFilters表达式支持多个位置更新。
以下查询替换sub3子女的所有子女。
db.collection_name.updateOne(
{'name': 'test'},
{'$set':{'children.$[first].children.$[second].children':[some data]}},
{'arrayFilters': [{ 'first.name': 'child2', 'second.name': 'sub3'}]}
)
以下查询在sub3孩子的子女中推送新孩子。
db.collection_name.updateOne(
{'name': 'test'},
{'$push':{'children.$[first].children.$[second].children':new child data}},
{'arrayFilters': [{ 'first.name': 'child2', 'second.name': 'sub3'}]}
)