MongoDB如何使用嵌套聚合计数
-
我需要对统计页面的注册收集数据进行分组和计数,以及进行动态注册,但是我无法得到多于一个分组的数据。 样本注册收集数据:
{ "_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 } } }]
我知道应该使用aggregate()函数,但是不知道怎么让它和count一起使用。 这是我的总体看起来像这样:
Registration .aggregate( { $group: { _id: { day: "$day", group: "$group" }, events: { $addToSet: { division: "$division", level: "$level"} }, total: { $sum: 1} } })
这返回每天/组合组合的总注册数,但是如果我尝试添加总计:{$ sum:1}到事件集,我只需要获得1。 有没有办法在一个数据库调用中使这项工作,或者我需要分别为需要计数的每个分组级别进行分析?
-
db.c1.insertMany([{
"_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"
}]) db.c1.mapReduce(
function() {
var key = {
day: this.day,
group: this.group
};
var ret = {
'count': 1,
'divisions': [{
'division': this.division,
'count': 1,
'levels':[{
'level': this.level,
'count': 1
}]
}]
}; emit(key, ret);
},
function(key,values) {
var c = 0;
var divisions = {};
var levels = {};
for(var i=0,ic=values.length;i<ic;++i){
c += values[i].count;
division_key = values[i].divisions[0]['division'];
if(division_key in divisions){
divisions[ division_key ]['count'] += 1;
divisions[ division_key ]['levels'].push( values[i].divisions[0]['levels'])
}else{
divisions[ division_key ] = {
count: 1,
levels: values[i].divisions[0]['levels']
}
}
}
var divisions_ret = [];
for(var k in divisions){
var levels={};
for(var m=0,mc=divisions[k]['levels'].length;m<mc;++m){
level_key = divisions[k]['levels'][m]['level'];
if(level_key in levels){
levels[ level_key ]['count'] += 1;
}else{
levels[ level_key ] = {
'count': 1,
'level': level_key
}
}
}
var level_ret = [];
for(var n in levels){
level_ret.push({
'level': n,
'count': levels[n]['count']
});
}
divisions_ret.push({
'division': k,
'count': divisions[k]['count'],
'levels': level_ret
});
}
var ret = {
'count': c,
'divisions': divisions_ret
};
return ret;
},
{
out: "a_result",
query: {}
}
);result:
{
"_id" : {
"day" : "Saturday",
"group" : "nonpro"
},
"value" : {
"count" : 3.0,
"divisions" : [
{
"division" : "Women's",
"count" : 1.0,
"levels" : [
{
"level" : "BB",
"count" : 1.0
}
]
},
{
"division" : "Men's",
"count" : 2.0,
"levels" : [
{
"level" : "BB",
"count" : 1.0
},
{
"level" : "undefined",
"count" : 1.0
}
]
}
]
}
}
{
"_id" : {
"day" : "Saturday",
"group" : "pro"
},
"value" : {
"count" : 2.0,
"divisions" : [
{
"division" : "Women's",
"count" : 1.0,
"levels" : [
{
"level" : "Pro",
"count" : 1.0
}
]
},
{
"division" : "Men's",
"count" : 1.0,
"levels" : [
{
"level" : "Pro",
"count" : 1.0
}
]
}
]
}
}
{
"_id" : {
"day" : "Sunday",
"group" : "nonpro"
},
"value" : {
"count" : 1.0,
"divisions" : [
{
"division" : "Coed",
"count" : 1.0,
"levels" : [
{
"level" : "BB",
"count" : 1.0
}
]
}
]
}
}
-
好文章, 值得收藏