Reputation: 8404
Can I limit the amount of find-results several times?
The reason being that I am adding now a sort option to the results of an existing application. I am already limiting the result set for pagination, but if I additionally sort, first the whole result would have to be sorted and then the result skipped/limited.
I don't care about 100% accurate results, but don't want to make the db too busy. So what I am trying is:
MyCollection.find(pattern).limit(somelargenumber).sort({score:desc}).skip(0).limit(10);
and that both for mongoose and the native mongodb driver.
Is that even possible? And.. does it make any sense?
(I would normally expect amount of documents returned for each query to be <100, but if someone somehow selects all documents, I want to prevent bad response time, and inaccurate results are ok for that case.)
Actually, from a quick test, I could not come up with a javascript query in the mongo command line - though it should be possible with the aggregation framework I think..
db.books.find().limit(1).sort({weightedRating:-1}).limit(10);
returns (as far as I can see) too many books (more than 1) and also the book has a great weightedRating, like not any random book would have (which should have been achieved by the first limit(1)).
Upvotes: 0
Views: 444
Reputation: 11671
Can I limit the amount of find-results several times?
No. If you do
db.test.find(query).limit(1).sort(sort).limit(10)
then all you have accomplished with .limit
is setting the limit to 10.
if I additionally sort, first the whole result would have to be sorted and then the result skipped/limited
Is your query, including the sort, indexed? If you have a query like
db.test.find({ "a" : 22 }).sort({ "b" : -1 })
and an index on { "a" : 1, "b" : -1 }
, then MongoDB can use the index to retrieve results in sorted order. The sort is free with the index.
It's hard to understand what you're looking for, but it sounds like you want to sort only the first N
results returned by a query, as opposed to returning the first N
results of a query for a given sort. It's possible using the aggregation framework:
db.test.aggregate([
{ "$match" : query },
{ "$limit" : limit },
{ "$sort" : sort }
])
This will sort just the limit
results of query
according to sort
. It will not return the first limit
results matching query as determined by the order sort
; it returns the limit
documents matching query
, ordered by sort
, with no guarantees about how those matching documents fit into the overall order of all results matching sort
. This will use an index for query
if one is available, and if limit
is relatively small (say < 100) the sort will not be expensive.
if someone somehow selects all documents, I want to prevent bad response time, and inaccurate results are ok for that case
Why not just have a default limit of, say, 100, if you are worried about returning too many results? The issue isn't really with how many documents are selected by the query if the query and sort aren't indexed - it's that many documents will have to be examined to find out which ones match and to put them in the right order.
Upvotes: 2