Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement paging in Mongodb?

Tags:

mongodb

I need to paginate a collection of articles (order by date - and nothing else). What is the standard way doing something like this in Mongodb?

I am not going to use the skip() method because of performance issues. Neither do I plan to use the $push method. The closest method I have seen is the range query method. But it seems to fail if any of the sorted items are removed.

like image 267
Lul Zilla Avatar asked Dec 05 '11 09:12

Lul Zilla


People also ask

How is pagination implemented?

For example, you can implement pagination using links to new pages on your ecommerce site, or using JavaScript to update the current page. Load more and infinite scroll are generally implemented using JavaScript.

What is skip and limit in pagination?

MongoDB has an extremely straightforward way to implement pagination: using skip and limit operations on a cursor. skip(n) skips n items in a query, while limit(m) returns only the next m items starting from the n-th one.

What is Skip method in MongoDB?

MongoDB skip() is used when we required a certain number of results after a certain number of documents simultaneously we have use skip method in MongoDB. If we want to skip a certain number of documents from the collection, skip method will skip the specified documents that we have used with the MongoDB skip method.


1 Answers

Range sorting should work well for you. First request will take first 10 items sorted by date:

db.articles.find({}).sort( { date : -1 } ).limit(10);

After this you will need store somewhere date of last item and use id in next paging request:

db.articles.find({"date": {$lt: storedDateOfLastItem}}).sort( { date : -1 } ).limit(10);

So, i guess it should work well for you. To estimate total count of pages you will need to use count.

But it seems to fail if any of the sorted items are removed.

If you will remove for example article from page #1 it for sure break page #2 because of stored last date will be changed. To avoid this you can estimate count of items that was before current saved date

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort( { date : -1 } ).count()

If this count was changed (let say 2 articled was removed). You need to updated storedDateOfLastItem

db.articles.find({"date": {$gt: storedDateOfLastItem}}).sort( { date : -1 } ).take(2)

Again taking storedDateOfLastItem from last item of above request and continue make paging.

But my opinion just keep this paging as it is without extra logic, because i suppose that article deletion is rare operation.

From mongodb documentation:

Paging Costs Unfortunately skip can be (very) costly and requires the server to walk from the beginning of the collection, or index, to get to the offset/skip position before it can start returning the page of data (limit). As the page number increases skip will become slower and more cpu intensive, and possibly IO bound, with larger collections.

Range based paging provides better use of indexes but does not allow you to easily jump to a specific page.

like image 56
Andrew Orsich Avatar answered Oct 17 '22 11:10

Andrew Orsich