Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongo aggregation framework unable to sort by two fields?

I am doing some aggregation on a mongo 2.4.9 collection but I am not able to sort the result by two fields. Here is the query I am making using PyMongo:

result = mongo_coll.aggregate([{"$match": {"_cls": "class1"},
                               {"$group": {"_id": {"currency": "$total.currency",
                                                   "v_id": "$v_id"},
                                           "total": {"$sum": "$total.amount"},
                                           "count": {"$sum": 1}}},
                               {"$sort": {"_id.currency": 1, "total": -1}}])

And I have the result sorted by "total":-1

If I replace the last line with the following:

                               {"$sort": {"total": -1, "_id.currency": 1}}])

It is still sorted by "total":-1

And if I replace it with the following:

                               {"$sort": {"_id.currency": 1}}])

It gets sorted by currency.

But I can't get it sorted how I want, which means by currency first, and then by total... (The results else look good, as expected). Anybody has a clue ?

Best and thanks in advance !

UPDATE: Here is a sample doc:

{
  "_id": { "$oid" : "533d0a3b830f783478a75aa1" },
  "_cls": "class1",
  "v_id": 6813,
  "total": {
    "amount": 680,
    "currency": "EUR",
    "exp": -2
  }
}
like image 610
Rmatt Avatar asked Apr 02 '14 16:04

Rmatt


1 Answers

I could actually find the reason why this is happening with Python thanks to the answer of Bernie in the MongoDB User Google Group:

Python dict are unordered and this is pretty sensible for doing ordering :-p

This is why the parameter could be given as a BSON.SON dict or as an OrderedDict to keep it more pythonic !

Here is the solution I used :

    from collections import OrderedDict
    sort_dict = OrderedDict()
    sort_dict['_id.currency'] = 1
    sort_dict['total'] = -1

And then

{"$sort": sort_dict}

EDIT The link from response in google user group...

like image 138
Rmatt Avatar answered Oct 07 '22 18:10

Rmatt