Map Reduce min, max, avg

2,427 views
Skip to first unread message

Brandon Hilkert

unread,
Feb 17, 2012, 12:15:35 PM2/17/12
to mongodb-user
I'm looking to get a min, max, and avg from a list of values, however
I can't seem to figure out what I'm doing wrong. When I tried to send
back the whole object, I get nothing, but when I use "result.min" i
get the desired results, but it just reports the one thing.

reduce =

function(key, values) {
var sum = 0;
var result = {min: 0, max: 0, avg: 0};

result.min = Math.min.apply(Math, values);
result.max = Math.max.apply(Math, values);

values.forEach(function(value){
sum += value;
});

result.avg = sum / values.length;

return result;
}

# => [{"_id"=>"user_algo", "value"=>{"min"=>NaN, "max"=>NaN,
"avg"=>NaN}}]



reduce =

function(key, values) {
var sum = 0;
var result = {min: 0, max: 0, avg: 0};

result.min = Math.min.apply(Math, values);
result.max = Math.max.apply(Math, values);

values.forEach(function(value){
sum += value;
});

result.avg = sum / values.length;

return result.avg;
}

# => [{"_id"=>"user_algo", "value"=>29.747736301092836}]


reduce =

function(key, values) {
var sum = 0;
var result = {min: 0, max: 0, avg: 0};

result.min = Math.min.apply(Math, values);
result.max = Math.max.apply(Math, values);

values.forEach(function(value){
sum += value;
});

result.avg = sum / values.length;

return result.min;
}

# => [{"_id"=>"user_algo", "value"=>0.046290512}]

Marc

unread,
Feb 17, 2012, 6:05:13 PM2/17/12
to mongodb-user
Good evening.

There are two articles in the MongoDB cookbook, which may help.
Finding Max And Min Values for a given Key
http://cookbook.mongodb.org/patterns/finding_max_and_min_values_for_a_key/
Finding Max And Min Values with Versioned Documents
http://cookbook.mongodb.org/patterns/finding_max_and_min/

You may find the "Extras" section of the second article especially
useful; It goes through a Map Reduce operation step-by-step and
explains what is output at each stage, and how the map and reduce
functions interact with each other.

Hopefully these examples will be close enough to your application to
get you where you need to go.

Please let us know if you have any follow-up questions!

Brandon Hilkert

unread,
Feb 17, 2012, 6:28:54 PM2/17/12
to mongodb-user
I did end up getting it to work. I was confused by the fact that it
seems that the map needs to emit a similar hash as what you're looking
to return in the reduce. Is that accurate?

I found that not including avg, min, and max in the map function
produced different results of those respective methods in the reduce
function.

This is what I ended up with:

map = %Q{
function() {
emit( this.type, {avg: parseFloat(this.data), total:
parseFloat(this.data), count: 1, min: parseFloat(this.data), max:
parseFloat(this.data) } );
}
}


reduce = %Q{
function(key, values) {
var result = {avg: 0.0, total: 0, count: 0.0, min:
values[0].min, max: values[0].max};

values.forEach(function(value){
result.count += value.count;
result.total += value.total;
if (value.max > result.max) { result.max =
value.max };
if (value.min < result.min) { result.min =
value.min };
});

result.avg = result.total / result.count;
return result;
}
}

On Feb 17, 6:05 pm, Marc <m...@10gen.com> wrote:
> Good evening.
>
> There are two articles in the MongoDB cookbook, which may help.
> Finding Max And Min Values for a given Keyhttp://cookbook.mongodb.org/patterns/finding_max_and_min_values_for_a...
> Finding Max And Min Values with Versioned Documentshttp://cookbook.mongodb.org/patterns/finding_max_and_min/

Marc

unread,
Feb 22, 2012, 10:03:12 AM2/22/12
to mongodb-user
Excellent! I am glad to hear that you were able to get this to work.
Yes, it is important that the output of the map function returns an
output in the same format as the reduce function, as you discovered.
Reply all
Reply to author
Forward
0 new messages