mapreduce function error with mongoose mapreduce function error with mongoose mongoose mongoose

mapreduce function error with mongoose


It looks like you have documents with "userto" and "userfrom" fields, and you want to sum the number of documents where "userfrom" exists for a particular "userto", grouping by "userfrom". Then you take the base 10 logarithm of each such sum and add 1. Since reduce can be called iteratively, as written this may end up taking the log of a partial sum and then taking the log of that result. This is possibly what is giving you trouble. You should therefore have mapReduce just get the counts, and take the log and add 1 afterwards. The following works for me, using mapReduce with 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"});

The input and output are:

# 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 }

Also, what version of MongoDB are you running? Upgrading might be helpful.

That said, for most aggregation tasks like this one, it is best to use MongoDB's aggregation framework, new in version 2.2. The aggregation framework was designed with performance and usability in mind, so its often preferred to mapReduce unless you're doing something specialized. The following solves the same problem using the aggregation framework instead of mapReduce:

db.foo.aggregate([  {$match: {userto: "sam"}},  {$group: {_id: "$userfrom", count: {$sum: 1}}}]);