Andreas Reiff
Andreas Reiff

Reputation: 8404

node.js mongodb driver and mongoose: multiple limits possible?

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

Answers (1)

wdberkeley
wdberkeley

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

Related Questions