Jer*_*oen 8 mongoose mongodb nosql
我正在寻找一种使用Mongo生成一些摘要统计数据的方法.假设我有一个包含许多表单记录的集合
{"name" : "Jeroen", "gender" : "m", "age" :27.53 }
Run Code Online (Sandbox Code Playgroud)
现在我想得到性别和年龄的分布.假设性别,只有价值"m"和"f".在我的收藏中获得男性和女性总数最有效的方法是什么?
而对于年龄,有没有办法做一些'binning'并给我一个像汇总的直方图; 即年龄在间隔内的记录数量:[0, 2), [2, 4), [4, 6) ...等等?
Jen*_*nna 20
我刚刚尝试了MongoDB 2.2版(2.2.0-rc0已经发布)中可用的新聚合框架,它应该比map reduce具有更高的性能,因为它不依赖于Javascript.
输入数据:
{ "_id" : 1, "age" : 22.34, "gender" : "f" }
{ "_id" : 2, "age" : 23.9, "gender" : "f" }
{ "_id" : 3, "age" : 27.4, "gender" : "f" }
{ "_id" : 4, "age" : 26.9, "gender" : "m" }
{ "_id" : 5, "age" : 26, "gender" : "m" }
Run Code Online (Sandbox Code Playgroud)
性别聚合命令:
db.collection.aggregate(
{$project: {gender:1}},
{$group: {
_id: "$gender",
count: {$sum: 1}
}})
Run Code Online (Sandbox Code Playgroud)
结果:
{"result" :
[
{"_id" : "m", "count" : 2},
{"_id" : "f", "count" : 3}
],
"ok" : 1
}
Run Code Online (Sandbox Code Playgroud)
为了获得箱子的年龄:
db.collection.aggregate(
{$project: {
ageLowerBound: {$subtract:["$age", {$mod:["$age",2]}]}}
},
{$group: {
_id:"$ageLowerBound",
count:{$sum:1}
}
})
Run Code Online (Sandbox Code Playgroud)
结果:
{"result" :
[
{"_id" : 26, "count" : 3},
{"_id" : 22, "count" : 2}
],
"ok" : 1
}
Run Code Online (Sandbox Code Playgroud)
康斯坦丁的回答是正确的。MapReduce 完成了工作。这是完整的解决方案,以防其他人觉得这很有趣。
为了统计性别,地图功能键是this.gender每条记录的属性。然后,reduce 函数将它们简单地相加:
// count genders
db.persons.mapReduce(
function(){
emit(this["gender"], {count: 1})
}, function(key, values){
var result = {count: 0};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}, {out: { inline : 1}}
);
Run Code Online (Sandbox Code Playgroud)
为了进行分箱,我们将映射函数中的键设置为向下舍入到最接近的除以二。因此,例如 10 到 11.9999 之间的任何值都将获得相同的密钥"10-12"。然后我们再次简单地将它们相加:
db.responses.mapReduce(
function(){
var x = Math.floor(this["age"]/2)*2;
var key = x + "-" + (x+2);
emit(key, {count: 1})
}, function(state, values){
var result = {count: 0};
values.forEach(function(value) {
result.count += value.count;
});
return result;
}, {out: { inline : 1}}
);
Run Code Online (Sandbox Code Playgroud)