Skip to content

Traditional Pagination Query ​

javascript
db.users
  .find(conditions)
  .sort({ _id: -1 })
  .skip((page - 1) * numberOfPage)
  .limit(numberOfPage);

The code above is a traditional, unoptimized pagination query based on page number and page size. The obvious drawback is that skip() must scan past the skipped documents, so it degrades badly on large collections.

Optimization ​

Typically the frontend passes a page number to the backend. Instead, the common optimization is to use a unique, indexed value as the query condition rather than skip(). The natural choice is _id: keep the _id of the last document from the previous page and query for documents whose _id is less than it.

javascript
// lastId is the _id of the last document from the previous page
db.users
  .find({ _id: { $lt: lastId }, ...conditions })
  .sort({ _id: -1 })
  .limit(numberOfPage)

ObjectID ​

I originally wrote quite a bit more here, but then found someone had already written a better article explaining ObjectID, so I'll defer to that.