使用嵌套聚合进行计数
问题描述:
我一直在尝试对统计页面的注册集合数据进行分组和计数,以及进行动态注册,但我无法让它计算多个分组。 抽样登记收集数据:使用嵌套聚合进行计数
{
"_id" : ObjectId("58ec60078cc818505fb75ace"),
"event" : "Women's BB",
"day" : "Saturday",
"group" : "nonpro",
"division" : "Women's",
"level" : "BB"
}
{
"_id" : ObjectId("58ec60078cc818505fb75acf"),
"event" : "Coed BB",
"day" : "Sunday",
"group" : "nonpro",
"division" : "Coed",
"level" : "BB"
}
{
"_id" : ObjectId("58ec60098cc818505fb75ad0"),
"event" : "Men's BB",
"day" : "Saturday",
"group" : "nonpro",
"division" : "Men's",
"level" : "BB"
}
{
"_id" : ObjectId("58ec60168cc818505fb75ad1"),
"event" : "Men's B",
"day" : "Saturday",
"group" : "nonpro",
"division" : "Men's",
"level" : "B"
}
{
"_id" : ObjectId("58ec60178cc818505fb75ad2"),
"event" : "Women's Open",
"day" : "Saturday",
"group" : "pro",
"division" : "Women's",
"level" : "Pro"
}
{
"_id" : ObjectId("58ec60188cc818505fb75ad3"),
"event" : "Men's Open",
"day" : "Saturday",
"group" : "pro",
"division" : "Men's",
"level" : "Pro"
}
我想重新组织,并做计数返回是这样的:
[ {_id: { day: "Saturday", group: "nonpro" },
count: 3,
divisions: [
{ division: "Men's",
count: 2,
levels: [
{ level: "BB", count: 1 },
{ level: "B", count: 1 }]
},
{ division: "Women's",
count: 1,
levels: [
{ level: "BB", count: 1 }]
}
},
{_id: { day: "Saturday", group: "pro" },
count: 2,
divisions: [
{ division: "Men's",
count: 1,
levels: [
{ level: "Pro", count: 1 }
},
{ division: "Women's",
count: 1,
levels: [
{ level: "Pro", count: 1 }]
}
},
{_id: { day: "Sunday", group: "nonpro" },
count: 1,
divisions: [
{ division: "Coed",
count: 1,
levels: [
{ level: "BB", count: 1 }
}
}]
我知道我应该使用聚合()函数,但我有很难让它和伯爵一起工作。这里是我的总的样子至今:
Registration
.aggregate(
{ $group: {
_id: { day: "$day", group: "$group" },
events: { $addToSet: { division: "$division", level: "$level"} },
total: { $sum: 1}
}
})
这将返回每天/组的组合总登记,但如果我尝试添加总数:{$总和:1}的事件设置,我只是得到1 (这是有道理的)。有一种方法可以在一次数据库调用中完成这项工作,还是需要为需要考虑的每个分组级别单独执行此操作?
答
您基本上需要3个级别的$group
流水线阶段。第一个将通过全部四个密钥对文件进行分组,即day
,group
,division
和level
。汇总 组的计数,这将成为level
的计数。
前面的组将采取三个键即day
,group
和division
和骨料计数将总结前面的组计数以及创建levels
阵列。
最后一组将是day
和group
键+ divisions
列表中嵌入前一组的结果。
考虑运行下面的管道的预期成果:
Registration.aggregate([
{
"$group": {
"_id": {
"day": "$day",
"group": "$group",
"division": "$division",
"level": "$level"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": {
"day": "$_id.day",
"group": "$_id.group",
"division": "$_id.division"
},
"count": { "$sum": "$count" },
"levels": {
"$push": {
"level": "$_id.level",
"count": "$count"
}
}
}
},
{
"$group": {
"_id": {
"day": "$_id.day",
"group": "$_id.group"
},
"count": { "$sum": "$count" },
"divisions": {
"$push": {
"division": "$_id.division",
"count": "$count",
"levels": "$levels"
}
}
}
}
], (err, results) => {
if (err) throw err;
console.log(JSON.stringify(results, null, 4));
})
样本输出
/* 1 */
{
"_id" : {
"day" : "Saturday",
"group" : "nonpro"
},
"count" : 3,
"divisions" : [
{
"division" : "Women's",
"count" : 1,
"levels" : [
{
"level" : "BB",
"count" : 1
}
]
},
{
"division" : "Men's",
"count" : 2,
"levels" : [
{
"level" : "BB",
"count" : 1
},
{
"level" : "B",
"count" : 1
}
]
}
]
}
/* 2 */
{
"_id" : {
"day" : "Saturday",
"group" : "pro"
},
"count" : 2,
"divisions" : [
{
"division" : "Women's",
"count" : 1,
"levels" : [
{
"level" : "Pro",
"count" : 1
}
]
},
{
"division" : "Men's",
"count" : 1,
"levels" : [
{
"level" : "Pro",
"count" : 1
}
]
}
]
}
/* 3 */
{
"_id" : {
"day" : "Sunday",
"group" : "nonpro"
},
"count" : 1,
"divisions" : [
{
"division" : "Coed",
"count" : 1,
"levels" : [
{
"level" : "BB",
"count" : 1
}
]
}
]
}
我的英雄!这完全符合我的需要。 $ group和“_id”之间的引号很重要,我不太明白,但我会随它一起去的! – user3561890