Reputation: 1503
Is there a way to specify the order of keys to sort by?
There seems to be some confusion in the comments. To be clear, I'm not asking about ascending or descending order. I'm asking if I can specify sorting priority.
For example, I want to sort by:
so that
pinned
value get sorted by score
, and pinned
and score
get sorted by newest
?In other words,
score
, newest
should never be considered if pinned
value is different (just sort by pinned
)newest
should never be considered if score
is different.For example,
{ pinned: false, score:1, _id: new }
{ pinned: true, score:1, _id: oldest }
{ pinned: false, score:2, _id: old }
should be ordered as
{ pinned: true, score: 1, _id: oldest }
{ pinned: false, score: 1, _id: new }
{ pinned: false, score: 2, _id: old }
Upvotes: 0
Views: 2478
Reputation: 42352
While JSON documents are unordered, in MongoDB there are several places where order matters. The most important ones to remember are:
When you specify a sort, the sort order will follow the order of fields, so in your case it would be .sort({pinned:1,score:1,newest:1})
you can see an example in the documentation.
Some operations expect fields in particular order.
It also matters for subdocuments if you are trying to match them (whereas top level field order in the query does not matter).
Upvotes: 2
Reputation: 4183
So I inserted some sample data as is in your question with mongo shell:
db.test.insert({ pinned: false, score:1, _id: "new" });
db.test.insert({ pinned: true, score:1, _id: "oldest" });
db.test.insert({ pinned: false, score:2, _id: "old" });
Try to sort it by:
db.test.find().sort({pinned: -1, score: 1, _id: 1})
It turns out the result is:
{ "_id" : "oldest", "pinned" : true, "score" : 1 }
{ "_id" : "new", "pinned" : false, "score" : 1 }
{ "_id" : "old", "pinned" : false, "score" : 2 }
Isn't that what you want?
EDIT: Keep in mind that JavaScript doesn't strictly obey JSON spec. e.g. JSON spec also says property names should quoted with ", JavaScript however you don't have to quote, or you can quote with '.
Upvotes: 1