Paginating large document collections in MongoDB using Node.js is implemented by chaining .skip() and .limit() methods onto query cursors.
flowchart LR
A["Client Requests Page 2 (pageSize = 5)"]
--> B["Calculate Skip = (2 - 1) * 5 = 5"]
--> C["cursor.find({}).skip(5).limit(5)"]
--> D["Skips first 5 docs & returns next 5 docs"]
import { MongoClient } from 'mongodb';
const uri = 'mongodb://127.0.0.1:27017';
const client = new MongoClient(uri);
async function getPaginatedProducts(page = 1, pageSize = 5) {
try {
await client.connect();
const db = client.db('kodersolution_no_sql');
const products = db.collection('products');
const skipAmount = (page - 1) * pageSize;
// Fetch paginated cursor
const paginatedDocs = await products
.find({})
.sort({ _id: 1 })
.skip(skipAmount)
.limit(pageSize)
.toArray();
const totalDocuments = await products.countDocuments();
const totalPages = Math.ceil(totalDocuments / pageSize);
console.log(`--- Page ${page} of ${totalPages} (Total: ${totalDocuments} Docs) ---`);
console.log(paginatedDocs);
} catch (err) {
console.error('MongoDB Limit Error:', err.message);
} finally {
await client.close();
}
}
getPaginatedProducts(2, 5);
.sort(): Always chain .sort() before .skip() and .limit() to ensure predictable pagination order across requests..skip() Offsets: High .skip() offsets (e.g. .skip(50000)) degrade performance because MongoDB scans and discards skipped documents; use Range/Bucket queries (_id: { $gt: lastId }) for deep pagination.countDocuments(): Use collection.countDocuments(filter) to get accurate total counts for pagination metadata.Calculate the .skip() value required for requesting Page 5 when displaying 20 items per page.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With