isotropic-2022
Share
Blog
Search
Menu

How To Implement Pagination in MongoDB

By James LePage
|
Last updated on July 8th, 2022
|

The concept of MongoDB pagination is interesting and complex. In this resource, we're going to take a look at several ways you can add pagination to your application using MongoDB as a database solution.

MongoDB is a document based data storage solution, so paging data is a common requirement. Pagination is also a resource intensive process, so doing at the database level is always a good idea.

There are a few methods that we can use to implement pagination in MongoDB (skip to solutions).

Use case: Pagination in MongoDB

Pagination is a universal concept in UI/UX. By definition, pagination breaks large datasets into smaller, more manageable chunks that users can easily navigate through.

Traditionally, they're paired with queries/filters/sorting.

isotropic-2022-07-08-at-15-18-17
Here are the pagination navigation controls on the Isotropic Blog archive

Let's say I've built a blog / content website with 100s of old posts, and new ones being added consistently.

I would want to show the 10 most recent published posts, and allow users to navigate through "chunks" of older posts.

I would use pagination with MongoDB to do just that.

mongo-db-pagnation
Now, let's implement!

Method one: Use Skip + Limit

This is the easiest way to implement pagination, but typically not the best or most efficient.

We will use:

First, the skip(n), where n equals the number of documents to skip over, essentially jumps over content. Then, the limit (n), where n equals the number of documents returned by the cursor, only shows a "chunk" of content.

By combining both, we can return 10 documents, and when moving to the next "page", we can skip over 10.

In the shell, here's what our commands would look like:

// Page 1 db.items.find().limit(10) // Page 2 db.items.find().skip(10).limit(10) // Page 3 db.items.find().skip(10).limit(10)

Easy pagination in MongoDB.

But, while this method works in a pinch, it's not the best option for large datasets.

isotropic-2022-07-08-at-15-31-47

That's because it scans the entire dataset from start to finish. Also, if a new document is added, it will mess up the pagination - this is an important, but overlooked consideration for more constantly updated applications.

Method two: range query (+ limit)

This method is actually recommended in the MongoDB documentation. Here's a direct quote:

Range queries can use indexes to avoid scanning unwanted documents, typically yielding better performance as the offset grows compared to using skip() for pagination.

This is a three step process. First choose a field with a UID, and one that changes consistently over time (for example, the _ID field which increases with every new doc addition).

Then, query for docs who has a field less than the start value. Mongo suggests using the _id field and implementing the $lt and sort() operators.

As a note, $lt will select documents where the value of _id is less than the specified value. Perfect for pagination and efficient too!

Finally, store the last-seen field value for the next query.

Here's example code from the MongoDB docs (as a js function):

function printStudents(startValue, nPerPage) { let endValue = null; db.students.find( { _id: { $lt: startValue } } ) .sort( { _id: -1 } ) .limit( nPerPage ) .forEach( student => { print( student.name ); endValue = student._id; } ); return endValue; }

This is a better method as it's more efficient and extendable. However it's a bit more complex.


And there are two ways that you can easily add pagination to MongoDB.

The Isotropic Codex is a collection of code snippets and education for WordPress, web and WooCommerce developers.
References
Subscribe & Share
If you liked this content, subscribe for our monthly roundup of WordPress news, website inspiration, exclusive deals and interesting articles.
Unsubscribe at any time. We do not spam and will never sell or share your email.
Subscribe
Notify of
guest
1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Alex
Alex
1 year ago

Hey, very good and concise post, love it!

just one thing - in your first code example fetching the 3rd page should look like

db.items.find().skip(20).limit(10)

but you skip 10

Article By
James LePage
Contributors/Editors
notloggedin
James LePage is the founder of Isotropic, a WordPress education company and digital agency. He is also the founder of CodeWP.ai, a venture backed startup bringing AI to WordPress creators.
We're looking for new authors. Explore Isotropic Jobs.
linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram