看起来您有带有“userto”和“userfrom”字段的文档,并且您想要对特定“userto”存在“userfrom”的文档数求和,按“userfrom”分组。然后你取每个这样的和的以 10 为底的对数并加 1。由于可以迭代地调用 reduce,如所写,这最终可能会取部分和的对数,然后取该结果的对数。这可能是给你带来麻烦的原因。因此,您应该让 mapReduce 只获取计数,然后获取日志并在之后加 1。以下对我有用,将 mapReduce 与 MongoDB 2.4.6 一起使用:
var id = "sam";
var query = {userto:id,userfrom:{$exists:true}};
var map = function () {
emit(this.userfrom, 1);
};
var reduce = function (id,emits) {
return Array.sum(emits);
};
db.foo.mapReduce(map, reduce, {
"query": query,
"out": "foo_out"
});
输入和输出是:
# input
{ "_id" : ObjectId("523750e41e31334eb99aae73"), "userfrom" : "dave", "userto" : "sam" }
{ "_id" : ObjectId("523750fa1e31334eb99aae74"), "userfrom" : "kyle", "userto" : "sam" }
{ "_id" : ObjectId("523753571e31334eb99aae75"), "userfrom" : "kyle", "userto" : "sam" }
{ "_id" : ObjectId("523753581e31334eb99aae76"), "userfrom" : "kyle", "userto" : "sam" }
{ "_id" : ObjectId("5237535c1e31334eb99aae77"), "userfrom" : "dave", "userto" : "sam" }
# output
{ "_id" : "dave", "value" : 2 }
{ "_id" : "kyle", "value" : 3 }
另外,您运行的是哪个版本的 MongoDB?升级可能会有所帮助。
也就是说,对于像这样的大多数聚合任务,最好使用 MongoDB 的聚合框架,版本 2.2 中的新功能。聚合框架的设计考虑了性能和可用性,因此它通常比 mapReduce 更受欢迎,除非您正在做一些专门的事情。以下使用聚合框架而不是 mapReduce 解决了相同的问题:
db.foo.aggregate([
{$match: {userto: "sam"}},
{$group: {_id: "$userfrom", count: {$sum: 1}}}
]);