[MONGOOSE] aggregate, page, limit (pagination) - fourslickz/notes GitHub Wiki

const mongoose = require('mongoose');

// Assuming you have a User model
const User = mongoose.model('User', new mongoose.Schema({
  name: String,
  age: Number,
  email: String
}));

async function getPaginatedUsers(page, limit) {
  try {
    const skip = (page - 1) * limit;

    const users = await User.aggregate([
      // Stage 1: Match (if any criteria, otherwise skip)
      // { $match: { age: { $gt: 18 } } }, // Optional filter

      // Stage 2: Sort (if needed)
      { $sort: { name: 1 } }, // Sort by name ascending

      // Stage 3: Pagination using $skip and $limit
      { $skip: skip },
      { $limit: limit },

      // Stage 4: (Optional) Project to include/exclude fields
      { $project: { name: 1, age: 1, email: 1 } }
    ]);

    console.log('Paginated Users:', users);
  } catch (error) {
    console.error('Error fetching paginated users:', error);
  }
}

// Example usage
getPaginatedUsers(2, 10); // Get the second page with 10 users per page

Explanation

Calculate skip Value:
    skip = (page - 1) * limit: This formula calculates the number of documents to skip based on the current page number and the limit of documents per page.

Aggregation Pipeline:
    $sort: Sort the documents (optional). In the example, users are sorted by name in ascending order. You can customize this to your needs.
    $skip: Skips the first skip number of documents.
    $limit: Limits the number of documents returned to the specified limit.

Run the Query:
    The aggregate() function runs the pipeline and returns the paginated results.

Example Output

Paginated Users: [
  { name: 'Alice', age: 29, email: '[email protected]' },
  { name: 'Bob', age: 35, email: '[email protected]' },
  ...
]

Additional

const totalDocuments = await User.countDocuments();
const totalPages = Math.ceil(totalDocuments / limit);