在最简单的意义上,这只是遵循 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:
嵌套数组
位置 $ 运算符不能用于遍历多个数组的查询,例如遍历嵌套在其他数组中的数组的查询,因为 $ 占位符的替换是单个值
现代 MongoDB
我们可以通过在此处应用$filter 和$map 来做到这一点。 $map 是真正需要的,因为“内部”数组可能会因“过滤”而发生变化,而“外部”数组当然与“内部”被剥离所有元素时的条件不匹配。
再次按照实际在每个数组中匹配多个属性的示例:
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"
}}
}}
])
这允许您“过滤”嵌套数组中的匹配项,以获得文档中的一个或多个结果。