Hi @Laks,
I’ll just give you some thoughts. But wait for a better answer.
tl;dr
Aggregation won’t alter sort and limit. But instead follows the order in the pipeline.
I’ve only tried it with one field, both indexed and not indexed.
Also, see the docs.
MQL
First, let’s take sort and limit separately.
sort will either
- Use an index to sort, if the sort key is indexed
- Do block-sort if the sort key is not indexed.
The latter normally takes more time, and if you include .sort({key:val}).explain()
at the end of your query, you can check whether is doing block sort or indexed sort. Block sort will appear with SORT on the query planner.
limit is simpler, and just restricts the stream coming out of a find query or match query.
But sort + limit is a bit different.
If you run:
db.zips.find().sort({"pop":-1}).limit(2).explain()
//or
db.zips.find().limit(2).sort({"pop":-1}).explain()
You get the same result, with or without indexes. But more important, the sort/limit order is irrelevant. Because we get the extreme values, sort is always done before limit.
Also take this line from the docs:
You can use sort()
in conjunction with limit()
to return the first (in terms of the sort order) k
documents, where k
is the specified limit.
The next paragraph in the docs is a bit confusing but it’s really repeating what I’ve quoted. As you said, limit and sort order don’t matter.
Aggregation
We can run the exact same queries on aggregation.
//you can include {$match:{}} if you like. Same output.
db.zips.aggregate([{$sort:{pop:-1}}, {$limit:2}])
// same result than find
db.zips.aggregate([{$limit:2}, {$sort:{pop:-1}}]
// different result
Aggregate is following the order in the pipeline, and not necessarily sorting in advance.