Pagination

Pagination

Pagination needs an explicit, stable order. skip and limit are straightforward for small offsets; large offsets may require an indexed range-based approach.

When working with large datasets, it's inefficient to retrieve all records at once. Instead, you can use pagination to fetch results in smaller chunks or pages. MongoDB provides three powerful methods to help with pagination:

  • limit(n) – Returns only the first n results
  • skip(n) – Skips the first n results
  • sort() – Orders the result set

Before working through the examples, make sure you can connect with mongosh and select your database. Use a practice database for writes and deletions.

  1. By the end of this lesson

    Calculate a page offset and sort with a unique tie-breaker before limiting results.

Step-by-Step: Setting Up Sample Data

First, let's create a sample articles collection with some dummy data for testing pagination.


    db.articles.insertMany([
      { title: "Article 1", author: "Alice", views: 120 },
      { title: "Article 2", author: "Bob", views: 90 },
      { title: "Article 3", author: "Charlie", views: 75 },
      { title: "Article 4", author: "David", views: 200 },
      { title: "Article 5", author: "Eve", views: 60 },
      { title: "Article 6", author: "Frank", views: 150 }
    ]);
    {
      "acknowledged": true,
      "insertedIds": [ ...ObjectId values... ]
    }

Using limit() to Fetch the First N Documents

If you only want to fetch the first 3 articles:


    db.articles.find().limit(3);
    [
      { title: "Article 1", author: "Alice", views: 120 },
      { title: "Article 2", author: "Bob", views: 90 },
      { title: "Article 3", author: "Charlie", views: 75 }
    ]

Explanation: limit(3) restricts the result to just the first 3 documents returned by the query.

Using skip() to Move to the Next Page

Example data reference: the following setup creates the records used below. If you already inserted them earlier in this lesson, do not insert them again.


    db.articles.insertMany([
      { title: "Article 1", author: "Alice", views: 120 },
      { title: "Article 2", author: "Bob", views: 90 },
      { title: "Article 3", author: "Charlie", views: 75 },
      { title: "Article 4", author: "David", views: 200 },
      { title: "Article 5", author: "Eve", views: 60 },
      { title: "Article 6", author: "Frank", views: 150 }
    ]);

Suppose you want to get the second page of results where each page shows 3 items:


    db.articles.find().skip(3).limit(3);
    [
      { title: "Article 4", author: "David", views: 200 },
      { title: "Article 5", author: "Eve", views: 60 },
      { title: "Article 6", author: "Frank", views: 150 }
    ]

Explanation: skip(3) skips the first 3 records. Combined with limit(3), it returns the next 3 documents — ideal for paginating through results.

Sorting with sort()

You can sort the documents by a field before paginating. For example, to sort by views in descending order:


    db.articles.find().sort({ views: -1 }).limit(3);
    [
      { title: "Article 4", author: "David", views: 200 },
      { title: "Article 6", author: "Frank", views: 150 },
      { title: "Article 1", author: "Alice", views: 120 }
    ]

Explanation: sort({ views: -1 }) arranges the documents from highest to lowest number of views. Then limit(3) fetches the top 3 most-viewed articles.

Combining limit(), skip(), and sort() for Full Pagination

Example data reference: the following setup creates the records used below. If you already inserted them earlier in this lesson, do not insert them again.


    db.articles.insertMany([
      { title: "Article 1", author: "Alice", views: 120 },
      { title: "Article 2", author: "Bob", views: 90 },
      { title: "Article 3", author: "Charlie", views: 75 },
      { title: "Article 4", author: "David", views: 200 },
      { title: "Article 5", author: "Eve", views: 60 },
      { title: "Article 6", author: "Frank", views: 150 }
    ]);

Let’s say we want to paginate sorted results — page 2, 3 results per page, sorted by views descending:


    db.articles.find().sort({ views: -1 }).skip(3).limit(3);
    [
      { title: "Article 2", author: "Bob", views: 90 },
      { title: "Article 3", author: "Charlie", views: 75 },
      { title: "Article 5", author: "Eve", views: 60 }
    ]

Explanation: First, the articles are sorted by views descending. Then we skip the first 3 and fetch the next 3 — perfect for page 2 of a paginated result set.

Common Pagination Formula


    db.collection.find()
      .sort({ field: 1 or -1 })
      .skip((pageNumber - 1) * pageSize)
      .limit(pageSize);

For example, for page 4 and page size 10:


    db.articles.find()
      .sort({ views: -1 })
      .skip((4 - 1) * 10)
      .limit(10);

Questions for Intuition

Q: Can I use skip without limit?

A: Yes, but that may return a large number of results. It's better to combine skip() with limit() to control result size.

Q: Can pagination slow down for large values of skip?

A: Yes, skip(n) has to scan and discard n documents. For very large datasets, consider using range-based pagination (e.g., using _id or timestamps).

What to remember

Pagination needs an explicit, stable order. skip and limit are straightforward for small offsets; large offsets may require an indexed range-based approach.

Summary

Pagination in MongoDB is achieved using limit(), skip(), and optionally sort() for ordered results. These methods let you efficiently retrieve data page-by-page — a common need in web and mobile applications.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Introduction to indexes →