在最简单的意义上,这只是遵循MongoDB使用的基本形式"dot notation".无论内部数组成员位于哪个数组成员中,只要它与一个值匹配,这都将起作用:
db.mycollection.find({
"someArray.someNestedArray.name": "value"
})
对于"单个字段"值来说,这很好,对于匹配多个字段,您可以使用$elemMatch
:
db.mycollection.find({
"someArray": {
"$elemMatch": {
"name": "name1",
"someNestedArray": {
"$elemMatch": {
"name": "value",
"otherField": 1
}
}
}
}
})
它与文档相匹配,文档中包含的内容在该"路径"处具有与值匹配的字段.如果您打算"匹配并过滤"结果,以便只返回匹配的元素,那么使用位置运算符投影as quoted:
Nested Arrays
positional$运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为$占位符的替换项是单个值
现代MongoDB
我们可以在这里应用$filter
和$map
.$map
是真正需要的,因为"内部"数组可能会因"过滤"而改变,"外部"数组当然不符合"内部"go 掉所有元素时的条件.
再次以每个数组中实际有多个要匹配的属性为例:
db.mycollection.aggregate([
{ "$match": {
"someArray": {
"$elemMatch": {
"name": "name1",
"someNestedArray": {
"$elemMatch": {
"name": "value",
"otherField": 1
}
}
}
}
}},
{ "$addFields": {
"someArray": {
"$filter": {
"input": {
"$map": {
"input": "$someArray",
"as": "sa",
"in": {
"name": "$$sa.name",
"someNestedArray": {
"$filter": {
"input": "$$sa.someNestedArray",
"as": "sn",
"cond": {
"$and": [
{ "$eq": [ "$$sn.name", "value" ] },
{ "$eq": [ "$$sn.otherField", 1 ] }
]
}
}
}
}
},
},
"as": "sa",
"cond": {
"$and": [
{ "$eq": [ "$$sa.name", "name1" ] },
{ "$gt": [ { "$size": "$$sa.someNestedArray" }, 0 ] }
]
}
}
}
}}
])
因此,在"外部"数组上,$filter
实际上是在"内部"数组本身被"过滤"后查看其$size
,因此当整个内部数组实际上不匹配时,可以拒绝这些结果.
老MongoDB
为了只"投影"匹配的元素,您需要.aggregate()
方法:
db.mycollection.aggregate([
// Match possible documents
{ "$match": {
"someArray.someNestedArray.name": "value"
}},
// Unwind each array
{ "$unwind": "$someArray" },
{ "$unwind": "$someArray.someNestedArray" },
// Filter just the matching elements
{ "$match": {
"someArray.someNestedArray.name": "value"
}},
// Group to inner array
{ "$group": {
"_id": {
"_id": "$_id",
"name": "$someArray.name"
},
"someKey": { "$first": "$someKey" },
"someNestedArray": { "$push": "$someArray.someNestedArray" }
}},
// Group to outer array
{ "$group": {
"_id": "$_id._id",
"someKey": { "$first": "$someKey" },
"someArray": { "$push": {
"name": "$_id.name",
"someNestedArray": "$someNestedArray"
}}
}}
])
这允许您在嵌套数组中"筛选"匹配项,以在文档中查找一个或多个结果.