0

I have a mongo collection with documents like-

{
_id : 1abc,
'data' :'blah',
'createdDate' : ISODate("2013-05-26T01:34:10Z"),
'a': [
    {
        _id : a1adas,
        'createdDate' : ISODate("2013-05-26T01:35:10Z"),
        'b':[
                {
                    _id : aadaasd
                    'createdDate' : ISODate("2013-05-26T01:37:10Z"),
                }
            ]
    }
]

}

I am required to sort the documents in reverse chronological order so that the document with the most recent createdDate , at any level, is first.

So far, I have this query, which I am not sure is working as expected.

db.collection.find({'data':'blah'}).sort({'createdDate':-1, 'a.createdDate': -1, 'a.b.createdDate': -1 }).explain();

I would like to know if there is a more efficient way of performing such a sort.

1 Answer 1

2

Your query isn't doing what you'd like it to do. A MongoDB sort on multiple fields will handle each field in turn, not all three fields together. For example, I've inserted a number of test documents into a collection and I've run a similar sort:

> db.numbers.find().sort( { a : -1, b : -1, c : -1 })
{ doc : "doc1", "a" : 13, "b" : 5, "c" : 7 }
{ doc : "doc2", "a" : 12, "b" : 20, "c" : 91 }
{ doc: "doc3", "a" : 2, "b" : 50, "c" : 700 }

"doc3" has the lowest value of a, so it is returned last. However, it also has the highest value of any field in the sort, so in theory we'd like it to be the first thing returned. We can do this using MongoDB's aggregation framework:

db.numbers.aggregate(
{ $project : { 
    _id : 1, 
    a : 1, 
    maxNum : { $cond: [{ $gte : [ "$b", "$c" ]}, "$b" , "$c" ]} // max of b, c
    }},
{ $project : { 
   _id : 1, 
   maxNum : { $cond: [{ $gte : [ "$a", "$maxNum" ]}, "$a" , "$maxNum" ]} // max of a, b, c 
   }}, 
{ $sort : { maxNum : -1 } } 
)

This aggregation query will transform your data into a form where your sort can be properly performed. However, it isn't easy to see how this performs. There is currently no .explain() function for aggregation queries.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.