Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting the highest value of a column in MongoDB

I've been for some help on getting the highest value on a column for a mongo document. I can sort it and get the top/bottom, but I'm pretty sure there is a better way to do it.

I tried the following (and different combinations):

transactions.find("id" => x).max({"sellprice" => 0}) 

But it keeps throwing errors. What's a good way to do it besides sorting and getting the top/bottom?

Thank you!

like image 553
roloenusa Avatar asked Jan 21 '11 19:01

roloenusa


People also ask

How does MongoDB calculate min max?

You need to use the . aggregate() method for it to work. For very large collections aggregating pipeline can be very slow because it scans each document. The solution mentioned here can be better if you need to find min/max of the indexed field: stackoverflow.com/a/6360583/3438640 Use find with sort and limit: db.

What is $first in MongoDB?

This means $first returns the first order type for the documents between the beginning of the partition and the current document.

What is $$ root in MongoDB?

The $$ROOT variable contains the source documents for the group. If you'd like to just pass them through unmodified, you can do this by $pushing $$ROOT into the output from the group.


2 Answers

max() does not work the way you would expect it to in SQL for Mongo. This is perhaps going to change in future versions but as of now, max,min are to be used with indexed keys primarily internally for sharding.

see http://www.mongodb.org/display/DOCS/min+and+max+Query+Specifiers

Unfortunately for now the only way to get the max value is to sort the collection desc on that value and take the first.

transactions.find("id" => x).sort({"sellprice" => -1}).limit(1).first() 
like image 129
Michael Papile Avatar answered Sep 29 '22 01:09

Michael Papile


Sorting might be overkill. You can just do a group by

db.messages.group(            {key: { created_at:true },             cond: { active:1 },             reduce: function(obj,prev) { if(prev.cmax<obj.created_at) prev.cmax = obj.created_at; },             initial: { cmax: **any one value** }             }); 
like image 40
Mayur Rustagi Avatar answered Sep 29 '22 03:09

Mayur Rustagi