Reputation: 714
TestSessionSchema.statics.getTopTesters = function(callback){
var o = {};
o.map = function(){
emit(this._customer, this.points);
};
o.reduce = function(_customer, values){
var result = {_customer: _customer, sum_points: 0, };
values.forEach(function(point){
result.sum_points += point;
});
return result;
};
o.out = { replace: 'createdCollectionNameForResults' };
o.verbose = true;
this.mapReduce(o,function(err, model, stats){
model.find().sort({'value.sum_points': "desc"}).limit(5).populate("_customer").exec(function(error, results){
log(results);
})
});
}
In map-reduce part I am geting _customers' points.
Now i want to populate _customer to get customers' info
model.find().sort({'value.sum_points': "desc"}).limit(5).populate("_customer")
does not work
how can I do it?
Upvotes: 1
Views: 715
Reputation: 42352
When you do mapReduce in MongoDB, you must make sure that your emit value has the same format as your reduce return value.
That means in your case that if map
calls emit(customer, points)
then reduce
must return simply the value for points
.
To change your specific example, your map function is okay, but your reduce function should be:
reduce = function(_customer, values) {
var result = 0;
values.forEach(function(point){
result += point;
});
return result;
};
Your reduce function would then sum up all of the values (points) for each _customer, which is what you want. The output would be _customer, point as key-value pairs with field names _id
and value
where value would be the sum of all the point values for that _id (_customer).
To query the result you would run:
db.createdCollectionNameForResults.find().sort({value:-1}).limit(5)
Upvotes: 1