Reputation: 92026
I want to sort on a MongoDB collection on some key in ascending order, and need the records that don't have the key to come last. e.g.
db.coll.find({}, {key: 1}).sort({key: 1})
gives:
{_id: 1}
{_id: 2, key: 1}
{_id: 3, key: 2}
but should give following instead:
{_id: 2, key: 1}
{_id: 3, key: 2}
{_id: 1}
Is there a way to do this with MongoDB?
Upvotes: 3
Views: 224
Reputation: 2981
I have a similar problem: I need to sort by text containing numbers in it, and numbers should be displayed AFTER strings. The only way we see for now is to create an indexed field where numbers are replaced with characters so they would be ranked after strings.
Upvotes: 0
Reputation: 25537
This can probably be done using the aggregation framework but it would be rather painful. You would have to replace the missing keys with a marker value that is higher than the valid keys (easy by using a key of a type that sorts after the type of key you have, unless the keys are regexes), then sort the collection, then strip out the marker values.
It would be more efficient to do it in two regular queries using $exist
.
Upvotes: 1
Reputation: 3150
Unfortunately mongoDB "when comparing values of different BSON types, MongoDB uses the following comparison order, from lowest to highest:" DOCS
When mongo generates the index it will include a null for those documents which has not got the key. You can do it with two queries, with using spare index for the first.
If you define a spare index on key field the sort will return only those which has value. This one will exclude the documents that has no key for it. DOCS
Upvotes: 3
Reputation: 18595
This is not possible. You will have to set "key" to the theoretically maximum value when you create the documents. Alternatively you can do two queries (one to get all where "key" exists sorted, and an optional other without the "key" set at all to complement your result set if needed). Usually the latter is not possible due to various business rule constraints.
Upvotes: 3