慕娘9325324
之前使用MapReduce做过类似的事情,因为耗时,后来修改成使用聚合查询做统计,具体示例如下:> db.user.findOne()
{ "_id" : ObjectId("557a53e1e4b020633455b898"), "accountId" : "55546fc8e4b0d8376000b858", "tags" : [ "金牌会员", "钻石会员", "铂金会员", "高级会员"
]
}基本的文档model如上,我在accountId和tags上做了索引db.user.ensureIndex({"accountId":1, "tags":1})现在要求统计用户下面的tags,MapReduce设计如下:var mapFunction = function() { if(this.tags){ for (var idx = 0; idx < this.tags.length; idx++) { var tag = this.tags[idx];
emit(tag, 1);
}
}
};var reduceFunction = function(key, values) { var cnt=0;
values.forEach(function(val){ cnt+=val;});
return cnt;
};
db.user.mapReduce(mapFunction,reduceFunction,{out:"mr1"}) //输出到集合mr1中结果:> db.mr1.find().pretty()
{ "_id" : "金牌会员", "value" : 9000 }
{ "_id" : "钻石会员", "value" : 43000 }
{ "_id" : "铂金会员", "value" : 90000 }
{ "_id" : "铜牌会员", "value" : 3000 }
{ "_id" : "银牌会员", "value" : 5000 }
{ "_id" : "高级会员", "value" : 50000 }看似达到我们的效果, 我只是拿少量的数据10W做的上面的测试, 执行的过程中,它会输出:> db.mapReduceTest.mapReduce(mapFunction,reduceFunction,{out:"mr1"}){ "result" : "mr1", "timeMillis" : 815, //耗时多久
"counts" : { "input" : 110000, //扫描的文档数量
"emit" : 200000, //mongo执行计算的次数
"reduce" : 2001, "output" : 6
}, "ok" : 1}因为我mock的数据比较简单有规律,可以看出它的计算次数几乎是扫描的文档数量的二倍,后来使用随机的数据做测试,发现结果更糟糕,果断放弃MapReduce的实现,改用其他实现。