Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo complex sorting?

Tags:

mongodb

I know how to sort queries in MongoDB by multiple fields, e.g., db.coll.find().sort({a:1,b:-1}).

Can I sort with a user-defined function; e.g., supposing a and b are integers, by the difference between a and b (a-b)?

Thanks!

like image 590
gilesc Avatar asked Jul 09 '10 13:07

gilesc


People also ask

Does MongoDB support sorting?

MongoDB can perform sort operations on a single-field index in ascending or descending order. In compound indexes, the sort order determines whether the index can be sorted. The sort keys must be listed in the same order as defined in the index.

How do I sort entries in MongoDB?

To sort documents in MongoDB, you need to use sort() method. The method accepts a document containing a list of fields along with their sorting order. To specify sorting order 1 and -1 are used. 1 is used for ascending order while -1 is used for descending order.

What sorting algorithm does MongoDB use?

If MongoDB cannot obtain the sort order via an index scan, then MongoDB uses a top-k sort algorithm. This algorithm buffers the first k results (or last, depending on the sort order) seen so far by the underlying index or collection access.


1 Answers

UPDATE: This answer appears to be out of date; it seems that custom sorting can be more or less achieved by using the $project function of the aggregation pipeline to transform the input documents prior to sorting. See also @Ari's answer.


I don't think this is possible directly; the sort documentation certainly doesn't mention any way to provide a custom compare function.

You're probably best off doing the sort in the client, but if you're really determined to do it on the server you might be able to use db.eval() to arrange to run the sort on the server (if your client supports it).

Server-side sort:

db.eval(function() {    return db.scratch.find().toArray().sort(function(doc1, doc2) {      return doc1.a - doc2.a    })  }); 

Versus the equivalent client-side sort:

db.scratch.find().toArray().sort(function(doc1, doc2) {    return doc1.a - doc2.b  }); 

Note that it's also possible to sort via an aggregation pipeline and by the $orderby operator (i.e. in addition to .sort()) however neither of these ways lets you provide a custom sort function either.

like image 94
mjs Avatar answered Sep 24 '22 21:09

mjs