MongoDB Pagination Techniques Explained

Ankit DwivediAnkit Dwivedi
3 min read

Pagination is a handy technique for displaying large amounts of data in smaller, more manageable chunks. This makes it easier for users to navigate and improves the performance of your application. In this guide, we'll go over how to implement pagination in MongoDB using easy-to-understand methods.

Why use Pagination?

When you have a lot of data, loading everything at once can slow down your application and overwhelm users. Pagination helps by:

  • Breaking down data into smaller pages.

  • Reducing the load on your server.

  • Making it easier for users to browse the data.

Key concepts

  • Page: A subset of your data.

  • Page Size (Limit): The number of items on each page.

  • Offset (Skip): The number of items to skip before starting to show the current page.

Pagination Methods in MongoDB

  1. Using Skip and Limit

The easiest way to paginate is by using MongoDB's skip and limit methods. This approach is straightforward but can be slow for large datasets.

const page = 1; // current page number
const limit = 10; // number of items per page

const comments = await Comment.find({ video: videoId })
    .skip((page - 1) * limit)
    .limit(limit);

Here, skip determines how many items to skip, and limit sets the number of items to return.

  1. Using Aggregation Framework

For more complex requirements, MongoDB's aggregation framework can be used. This is useful if you need to perform additional operations like sorting or joining with other collections.

Example:

const page = 1;
const limit = 10;

const comments = await Comment.aggregate([
    { $match: { video: videoId } },
    { $sort: { createdAt: -1 } },
    { $skip: (page - 1) * limit },
    { $limit: limit },
    {
        $lookup: {
            from: 'users',
            localField: 'owner',
            foreignField: '_id',
            as: 'ownerDetails'
        }
    },
    { $unwind: '$ownerDetails' },
    {
        $project: {
            content: 1,
            'ownerDetails.username': 1,
            'ownerDetails.avatar': 1,
            createdAt: 1
        }
    }
]);

The aggregate method allows you to chain multiple operations together, making it very powerful.

Implementing Pagination in a RESTful API

const getVideoComments = asyncHandler(async (req, res) => {
    const { videoId } = req.params;
    const { page = 1, limit = 10 } = req.query;

    if (!isValidObjectId(videoId)) {
        throw new ApiError(400, 'Invalid video ID');
    }

    const comments = await Comment.find({ video: videoId })
        .populate('owner', 'username avatar')
        .skip((page - 1) * limit)
        .limit(Number(limit))
        .sort({ createdAt: -1 });

    if (!comments.length) {
        throw new ApiError(404, 'No comments found for this video');
    }

    return res.status(200).json(
        new ApiResponse(200, comments, 'Comments fetched successfully')
    );
});

In this function, we:

  1. Get the video ID from the URL parameters and the page and limit from the query string.

  2. Check if the video ID is valid.

  3. Fetch the comments for the given video, paginated and sorted by creation date, and include user details.

Conclusion:

Pagination is essential for handling large datasets in a user-friendly and efficient way. Whether you use skip and limit or the aggregation framework depends on your needs and the complexity of your queries. With proper pagination, you can improve both the performance and usability of your application.

Happy Coding!

0
Subscribe to my newsletter

Read articles from Ankit Dwivedi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Ankit Dwivedi
Ankit Dwivedi