[英]MongoDB query embedded document array
I have the following document: 我有以下文件:
{
"_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"
}
]
}
]
}
]
}
And I would like to get a list of all devices: 我想获取所有设备的列表:
[
{
"_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"
}
]
Is that possible with MongoDB? MongoDB有可能吗?
I've tried it with aggregate and { $unwind: $floors.rooms.devices }
or 我已经尝试使用汇总和
{ $unwind: $floors.rooms.devices }
或
{ $unwind: $floors }
{ $unwind: $floors.rooms }
{ $unwind: $floors.rooms.devices }
but the output is always empty. 但输出始终为空。 I don't know if I would get the output I want with $unwind at all.
我不知道是否可以用$ unwind得到我想要的输出。
Because I'm also using aggregate for other things a solution with it would be nice. 因为我还在将聚合用于其他用途,所以有一个很好的解决方案。
You can use $reduce
to collect all the devices inside all rooms across all floors in a single document in 3.4 version. 您可以使用
$reduce
在3.4版本的单个文档中收集所有楼层所有房间内的所有设备。
The below query has two parts inner reduce and outer reduce. 下面的查询有两个部分:内部归约和外部归约。
The inner reduce will collect all the devices, $reduc
ing one room at a time and concatenating with the previous room's devices arrays in a single floor element. 内减少将收集所有的设备,
$reduc
荷兰国际集团一次在一个房间,在一个单一的地板单元前面的房间的设备阵列串联。
The output from the inner reduce is piped to the outer $reduce
to concat devices across all floors. 内部reduce的输出通过管道传递到外部
$reduce
以连接所有楼层的设备。
Something like 就像是
db.collection.aggregate(
[{
"$project": {
"_id": 0,
"devices": {
"$reduce": {
"input": "$floors",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
{
"$reduce": {
"input": "$$this.rooms",
"initialValue": [],
"in": {
"$concatArrays": [
"$$value",
"$$this.devices"
]
}
}
}
]
}
}
}
}
}]
)
For MongoDB Version < 3.4 对于MongoDB版本<3.4
You can use the below pipeline. 您可以使用以下管道。 Use
preserveNullAndEmptyArrays
option on $unwind
to prevent pipeline from dropping documents when any of the below arrays is missing, null or empty. 在
$unwind
上使用preserveNullAndEmptyArrays
选项可防止在缺少以下任何数组,null或为空时管道丢失文档。
db.collection.aggregate(
[
{ "$unwind": "$floors" },
{ "$unwind": "$floors.rooms" },
{ "$unwind": "$floors.rooms.devices" },
{ "$group":{ "_id":"$_id", "devices":{ "$push":"$floors.rooms.devices"} } }
]
)
I think you are looking for this: 我认为您正在寻找:
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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.