Sling Academy
Home/Node.js/LIMIT and SKIP in Mongoose (with examples)

LIMIT and SKIP in Mongoose (with examples)

Last updated: December 30, 2023

Introduction

Diving into the world of MongoDB with Mongoose as our ODM (Object Document Mapping) tool, we realize that handling large amounts of data efficiently is crucial. Mongoose provides the limit() and skip() methods for this exact purpose, enabling efficient data pagination and subset retrieval in a Node.js application. In this tutorial, we will explore how to employ these methods with several examples, starting from basic usage to more advanced scenarios in the context of modern JavaScript or TypeScript.

Basic Use of LIMIT and SKIP

The limit() method in Mongoose restricts the number of documents returned in a query, while skip() bypasses a specified number of documents. Together, they are indispensable for pagination. Let’s look at a basic example:

// Importing the necessary modules
import mongoose from 'mongoose';
const { Schema } = mongoose;

// Define a simple User schema
const UserSchema = new Schema({
  username: String,
  createdAt: Date
});
const User = mongoose.model('User', UserSchema);

// Fetch 10 users, skip the first 5
async function fetchUsers() {
  try {
    const users = await User.find()
                           .skip(5)
                           .limit(10)
                           .exec();
    return users;
  } catch (err) {
    console.error(err);
  }
}

fetchUsers().then(users => console.log(users));

Dynamic Pagination Using Query Parameters

In real-world applications, pagination values often come from client-side requests. Here is an example of implementing dynamic pagination based on query parameters:

// Function to paginate user results dynamically
async function paginateUsers(req) {
  let { page, perPage } = req.query;
  page = parseInt(page, 10) || 1;
  perPage = parseInt(perPage, 10) || 10;

  try {
    const users = await User.find()
                           .skip((page - 1) * perPage)
                           .limit(perPage)
                           .exec();
    return users;
  } catch (err) {
    console.error(err);
  }
}

Advanced Query Combination with SORT and SELECT

Now let’s advance to combining limit() and skip() with other query methods like sort() and select() :

// Using sort, limit, skip, and select together
async function fetchSortedUsers() {
  try {
    const users = await User.find()
                           .select('username createdAt')
                           .sort('-createdAt')
                           .skip(5)
                           .limit(10)
                           .exec();
    console.log('Sorted users:', users);
  } catch (err) {
    console.error('Error retrieving users:', err);
  }
}

Combining Aggregation with LIMIT and SKIP

Mongoose aggregation pipeline is a powerful feature that provides more flexibility than simple queries. Here, we utilize $limit and $skip within an aggregation framework:

// Using aggregation with limit and skip
async function aggregateUsers() {
  try {
    const users = await User.aggregate([
      { $match: { /* criteria */ } },
      { $sort: { createdAt: -1 } },
      { $skip: 5 },
      { $limit: 10 },
      { $project: { username: 1, createdAt: 1 } }
    ]);

    console.log('Aggregated users:', users);
  } catch (err) {
    console.error('Error in aggregation:', err);
  }
}

Final Words

Through this tutorial, we’ve covered how to use limit() and skip() methods in Mongoose effectively to handle data pagination and retrieval. Learning to combine these methods with sort, select, and MongoDB’s aggregation pipeline broadens their application, optimizing queries and transforming our approach to data management in Node.js applications with Mongoose as an ODM. As you master these techniques, you equip yourself with one of the foundations of creating scalable and user-friendly APIs.

Remember when using skip() and limit(), the performance aspects should not be overlooked, especially for large datasets where they can introduce significant performance penalties. Indexing and careful query structuring will play an important role in mitigating those effects.

Go forth and paginate responsibly!

Next Article: What is the equivalent of SQL ‘GROUP BY’ in Mongoose?

Previous Article: Fixing Mongoose Error: QuerySrv ESERVFAIL

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates