How to implement paging in Mongodb?

I need to break up a collection of articles (order by date - and nothing more). What is the standard way to do something like this in Mongodb?

I will not use the skip () method due to performance issues. I also do not plan to use the $ push method. The closest method I've seen is a range request method. But it seems to fail if any of the sorted items is deleted.

+7
source share
2 answers

Range sorting should work well for you. The first request will take the first 10 elements, sorted by date:

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

After that, you will need to store the date of the last element somewhere and use the identifier in the following search query:

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

So, I think this should work for you. To estimate the total number of pages, you will need to use count .

But it does not seem to work if any of the sorted items are deleted.

If you delete, for example, an article from page # 1, it is imperative that page No. 2 break be changed due to the last date saved. To avoid this, you can estimate the number of items that were before the current saved date.

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

If this account has been changed (for example, 2 articulates were deleted). You need to update storedDateOfLastItem

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

Again, take storedDateOfLastItem from the last element of the above request and continue to do swap.

But my opinion simply keeps this paging, because it is without too much logic, because I believe that deleting an article is a rare operation.

From the mongodb documentation:

Paging costs Unfortunately, skipping can be (very) expensive and requires the server to go from the beginning of the collection or index to get to the offset / skip position before it can start returning the page data (limit). As the number of pages increases, skipping will be a slower and more intensive processor, and possibly related to IO, with large collections.

Range-based paging provides the best use of indexes, but does not allow you to easily go to a specific page.

+9
source

If you can sort by index, effective pagination can be implemented using query modifiers "$ min" and "$ max" or a range query. Make sure your index contains a unique property at the end (for example, "_id").

If you cannot sort by index, you can pre-process the full set of results and keep the list of "_id" values ​​in order. Then you can take the range of this list and find the results page using the query operator "$ in".

0
source

All Articles