我有以下文件:
{
"_id" : ObjectId("59299670266cc82a042f3817"),
"_userId" : ObjectId("590a08dba07c1a1bee87b310"),
"name" : "My home",
"floors" : [
{
"_id" : ObjectId("59299670266cc82a042f4541"),
"name" : "Floor 1",
"rooms" : [
{
"_id" : ObjectId("59299670266cc82a042f4551"),
"name" : "Room 1",
"devices" : [
{
"_id" : ObjectId("59299670266cc82a042f4561"),
"name" : "Device 1"
},
{
"_id" : ObjectId("59299670266cc82a042f4562"),
"name" : "Device 2"
}
]
},
{
"_id" : ObjectId("59299670266cc82a042f4552"),
"name" : "Room 2",
"devices" : [
{
"_id" : ObjectId("59299670266cc82a042f4563"),
"name" : "Device 3"
},
{
"_id" : ObjectId("59299670266cc82a042f4564"),
"name" : "Device 4"
}
]
}
]
},
{
"_id" : ObjectId("59299670266cc82a042f4542"),
"name" : "Floor 2",
"rooms" : [
{
"_id" : ObjectId("59299670266cc82a042f4553"),
"name" : "Room 1",
"devices" : [
{
"_id" : ObjectId("59299670266cc82a042f4565"),
"name" : "Device 5"
},
{
"_id" : ObjectId("59299670266cc82a042f4566"),
"name" : "Device 6"
}
]
},
{
"_id" : ObjectId("59299670266cc82a042f4554"),
"name" : "Room 2",
"devices" : [
{
"_id" : ObjectId("59299670266cc82a042f4567"),
"name" : "Device 7"
},
{
"_id" : ObjectId("59299670266cc82a042f4568"),
"name" : "Device 8"
}
]
}
]
}
]
}
我想获得所有设备的列表:
[
{
"_id" : ObjectId("59299670266cc82a042f4561"),
"name" : "Device 1"
},
{
"_id" : ObjectId("59299670266cc82a042f4562"),
"name" : "Device 2"
},
{
"_id" : ObjectId("59299670266cc82a042f4563"),
"name" : "Device 3"
},
{
"_id" : ObjectId("59299670266cc82a042f4564"),
"name" : "Device 4"
},
{
"_id" : ObjectId("59299670266cc82a042f4565"),
"name" : "Device 5"
},
{
"_id" : ObjectId("59299670266cc82a042f4566"),
"name" : "Device 6"
},
{
"_id" : ObjectId("59299670266cc82a042f4567"),
"name" : "Device 7"
},
{
"_id" : ObjectId("59299670266cc82a042f4568"),
"name" : "Device 8"
}
]
MongoDB有可能吗?
我已尝试使用聚合和{ $unwind: $floors.rooms.devices }
或
{ $unwind: $floors }
{ $unwind: $floors.rooms }
{ $unwind: $floors.rooms.devices }
但输出始终为空。我不知道我是否会以$ unwind取得我想要的输出。
因为我也在使用聚合作为其他东西,所以解决它会很好。
答案 0 :(得分:1)
您可以使用$reduce
收集3.4版本单个文档中所有楼层内所有房间内的所有设备。
以下查询有两个部分:inner reduce和outer reduce。
内部缩减将收集所有设备,$reduc
一次一个房间,并与单个楼层元素中的前一个房间的设备阵列连接。
内部缩减的输出通过管道连接到外部$reduce
到所有楼层的连接设备。
像
这样的东西db.collection.aggregate(
[{
"$project": {
"_id": 0,
"devices": {
"$reduce": {
"input": "$floors",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
{
"$reduce": {
"input": "$$this.rooms",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
"$$this.devices"
]
}
}
}
]
}
}
}
}
}]
)
对于MongoDB版本< 3.4
您可以使用以下管道。在preserveNullAndEmptyArrays
上使用$unwind
选项可防止管道在以下任何数组丢失,空或空时删除文档。
db.collection.aggregate(
[
{ "$unwind": "$floors" },
{ "$unwind": "$floors.rooms" },
{ "$unwind": "$floors.rooms.devices" },
{ "$group":{ "_id":"$_id", "devices":{ "$push":"$floors.rooms.devices"} } }
]
)
答案 1 :(得分:1)
我认为你正在寻找这个:
db.collection.aggregate([
{$match: {}},
{$unwind: "$floors"},
{$unwind: "$floors.rooms"},
{$unwind: "$floors.rooms.devices"},
{$group: {
_id: "$floors.rooms._id",
d1: {$push: "$floors.rooms.devices"}
}},
{$unwind:"$d1"},
{$group: {
_id: "ignore-me",
devices: {$push: "$d1"}
}}
]).pretty();