如何从Array内的Array查询对象,并将其作为顶级对象获取?例如,请考虑以下记录。
{
"subjects": [
{
"name": "English",
"teachers": [
{
"name": "Mark" /* Trying to get this object*/
},
{
"name": "John"
}
]
}
]
}
我试图将以下对象作为顶级对象。
{
"name": "Mark"
}
答案 0 :(得分:1)
您需要使用aggregation框架来完成您所要求的工作。
在这里,我输入了你收藏的文件:foo。
> db.foo.find().pretty()
{
"_id" : ObjectId("57ceed3d31484d5b491eaae9"),
"subjects" : [
{
"name" : "English",
"teachers" : [
{
"name" : "Mark"
},
{
"name" : "John"
}
]
}
]
}
使用$ unwind解开我们的数组,然后我们进入聚合管道的第一阶段:
> db.foo.aggregate([
... {$unwind: "$subjects"}
... ]).pretty()
{
"_id" : ObjectId("57ceed3d31484d5b491eaae9"),
"subjects" : {
"name" : "English",
"teachers" : [
{
"name" : "Mark"
},
{
"name" : "John"
}
]
}
}
主题是一个长度为1的数组,所以这里唯一的区别就是少了一组[]数组括号。
我们需要再次放松。
> db.foo.aggregate([
... {$unwind: "$subjects"},
... {$unwind: "$subjects.teachers"}
... ]).pretty()
{
"_id" : ObjectId("57ceed3d31484d5b491eaae9"),
"subjects" : {
"name" : "English",
"teachers" : {
"name" : "Mark"
}
}
}
{
"_id" : ObjectId("57ceed3d31484d5b491eaae9"),
"subjects" : {
"name" : "English",
"teachers" : {
"name" : "John"
}
}
}
现在我们将长度为'2'的数组转换为两个单独的文档。第一个是subjects.teachers.name = Mark,第二个是subjects.teachers.name = John。
我们只想返回name = Mark的情况,因此我们需要在我们的管道中添加$ match阶段。
> db.foo.aggregate([
... {$unwind: "$subjects"},
... {$unwind: "$subjects.teachers"},
... {$match: {"subjects.teachers.name": "Mark"}}
... ]).pretty()
{
"_id" : ObjectId("57ceed3d31484d5b491eaae9"),
"subjects" : {
"name" : "English",
"teachers" : {
"name" : "Mark"
}
}
}
确定!现在我们只匹配名称为Mark的案例。
让我们添加一个$ project案例来塑造我们想要的输入。
> db.foo.aggregate([
... {$unwind: "$subjects"},
... {$unwind: "$subjects.teachers"},
... {$match: {"subjects.teachers.name": "Mark"}},
... {$project: {"name": "$subjects.teachers.name", "_id": 0}}
... ]).pretty()
{ "name" : "Mark" }