(请参见下面的修改)
我正在尝试在同一个MongoDB数据库中聚合来自两个单独集合的数据。
“帐户”集合包含用户信息(已清除):
{
_id: ObjectId("5c0d64a4224a2900108c005f"),
"username" : "mike22",
"email" : "mike22@<domain>.com",
"country" : GB,
"created" : ISODate("2018-11-26T23:37:49.051Z")
},
{
_id: ObjectId("5a0d64a4527h2880108c0445"),
"username" : "mike23",
"email" : "mike23@<domain>.com",
"country" : DE,
"created" : ISODate("2018-11-26T23:37:49.051Z")
},
{
_id: ObjectId("5a3334a45zzz2884448c0445"),
"username" : "mike24",
"email" : "mike24@<domain>.com",
"country" : DE,
"created" : ISODate("2018-11-26T23:37:49.051Z")
}
“设备”集合包含所有用户的设备定义。用户可能在此集合中定义了许多设备,并且该集合中有许多用户设备。
此集合中的单个设备定义如下:
{
"_id" : ObjectId("5c10138c73bbe0001018e415"),
"capabilities" : [
"BrightnessController",
"PowerController"
],
"displayCategories" : [
"LIGHT"
],
"friendlyName" : "Test1",
"description" : "Test device 1",
"reportState" : true,
"username" : "mike22",
"endpointId" : 11,
"__v" : 0
},
{
"_id" : ObjectId("5c10138c73bbe0001018e415"),
"capabilities" : [
"PowerController"
],
"displayCategories" : [
"SWITCH"
],
"friendlyName" : "Test2",
"description" : "Test device 2",
"reportState" : true,
"username" : "mike23",
"endpointId" : 12,
"__v" : 0
},
{
"_id" : ObjectId("5c10138c73bbe0001018e415"),
"capabilities" : [
"PowerController"
],
"displayCategories" : [
"SMARTPLUG"
],
"friendlyName" : "Test3",
"description" : "Test device 3",
"reportState" : true,
"username" : "mike22",
"endpointId" : 13,
"__v" : 0
}
我可以使用下面的汇总向我显示每位用户的设备计数:
db.accounts.aggregate([
{
$lookup: {
from : "devices",
localField : "username",
foreignField : "username",
as : "userdevs"
},
},
{ $unwind:"$userdevs" },
{ $group : { _id : "$username", count : { $sum : 1 } } }
])
上面的数据/汇总中的示例输出:
{ "_id" : "mike22", "count" : 2 },
{ "_id" : "mike23", "count" : 1 }
(注意,现在没有设备的用户不见了,应该在那里计数为零吗?!)
但是,我想返回每个用户的所有字段 plus 一个新字段,该字段向我显示他们在“设备”集合中拥有的设备数量。我正在寻找的输出如下:
{
"_id" : ObjectId("5c0d64a4224a2900108c005f"),
"username" : "mike22",
"email" : "mike22@<domain>.com",
"country" : GB,
"created" : ISODate("2018-11-26T23:37:49.051Z"),
"countDevices": 2
},
{
"_id" : ObjectId("5a0d64a4527h2880108c0445"),
"username" : "mike23",
"email" : "mike23@<domain>.com",
"country" : DE,
"created" : ISODate("2018-11-26T23:37:49.051Z"),
"countDevices": 1
},
{
"_id" : ObjectId("5a0d64a4527h2880108c0445"),
"username" : "mike24",
"email" : "mike24@<domain>.com",
"country" : DE,
"created" : ISODate("2018-11-26T23:37:49.051Z"),
"countDevices": 0
}
编辑16/12:因此,下面的汇总信息差不多可以了。零计数的用户却丢失了。
use users
db.accounts.aggregate([
{
$lookup: {
from : "devices",
localField : "username",
foreignField : "username",
as : "userdevs"
},
},
{ $unwind: "$userdevs"},
{ $group : { _id : {
_id: "$_id",
username: "$username",
email: "$email",
country: "$country",
region: "$region",
},
countDevices : { $sum : 1 } } }
])
第二次编辑16/12:
我在下面找到了所需的汇总:
db.accounts.aggregate([
{ "$lookup": {
"from": "devices",
"let": { "username": "$username" },
"pipeline": [
{ "$match": {
"$expr": { "$eq": [ "$$username", "$username" ] }
}},
{ "$count": "count" }
],
"as": "deviceCount"
}},
{ "$addFields": {
"countDevices": { "$sum": "$deviceCount.count" }
}}
])
答案 0 :(得分:0)
首先,您可以使用如下所示的投影来展平答案:
{ $project : {
_id : '$_id._id',
username : '$_id.username',
email : '$_id.email',
country : '$_id.country',
region : '$_id.region',
countDevices: 1
}
}
将其添加到管道中的$ group之后,您将获得问题中想要的结果。
关于零计数用户,有一种方法可以使用mongoDB在数据库中处理此问题,如详细here所述,但我不建议这样做,最好由您来处理客户端有问题。
答案 1 :(得分:0)
每秒编辑一次,我使用的汇总如下:
db.accounts.aggregate([
{ "$lookup": {
"from": "devices",
"let": { "username": "$username" },
"pipeline": [
{ "$match": {
"$expr": { "$eq": [ "$$username", "$username" ] }
}},
{ "$count": "count" }
],
"as": "deviceCount"
}},
{ "$addFields": {
"countDevices": { "$sum": "$deviceCount.count" }
}}
])