使用嵌套聚合进行计数

问题描述:

我一直在尝试对统计页面的注册集合数据进行分组和计数,以及进行动态注册,但我无法让它计算多个分组。 抽样登记收集数据:使用嵌套聚合进行计数

{ 
     "_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,divisionlevel。汇总 组的计数,这将成为level的计数。

前面的组将采取三个键即daygroupdivision和骨料计数将总结前面的组计数以及创建levels阵列。

最后一组将是daygroup键+ 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 
       } 
      ] 
     } 
    ] 
} 
+1

我的英雄!这完全符合我的需要。 $ group和“_id”之间的引号很重要,我不太明白,但我会随它一起去的! – user3561890