Paging Using the Aggregation Framework

In this video we’ll use the MongoDB Aggregation Framework to create a way to page our collection into manageable chunks and even take it a bit further with some fancy features that the Aggregation Framework gives us.

As you collections get bigger and bigger you will likely want to be able to page the documents from your collect, in other words get back a certain number of documents (per page) at a time and keep track of where you are.

You can learn more about the MongoDB VS Code extension here.

Basic Example

use("mongoquest");

db.getCollection("questions").find({}).sort({ number: 1 }).skip(5).limit(5);

Using the Aggregation Framework

use("mongoquest");

const getPage = (page = 0) =>
  db.getCollection("questions").aggregate(
    [
      { $sort: { number: 1 } }, 
      { $skip: page * 5 }, 
      { $limit: 5 }
    ]
  );

getPage(3);

Page Results By Level

use("mongoquest");

const getLevelPage = (level, page = 0) =>
  db.getCollection("questions").aggregate(
    [
      { $match: { level } }, 
      { $project: { question: 1 } },
      
      { $sort: { number: 1 } }, 
      { $skip: page * 5 }, 
      { $limit: 5 }
    ]
  );

getLevelPage(2,3);

// this will get level 2 questions, and skip to the 3rd page
// so we only get 4 results, the only ones left

Advanced Usage

use("mongoquest");

const getLevelPageWithPosition = (page = 0) =>
  db.getCollection("questions").aggregate([

  // get total count and assign to totalCount field
  { $setWindowFields: { 
      output: {
        totalCount: { $count: {} }
      }
    }
  },

  // sort, skip, limit
  { $sort: { number: 1 } }, 
  { $skip: page * 5 }, 
  { $limit: 5 },

  // get and add the ordered resultNumber field
  { $setWindowFields: {
      sortBy: { number: 1 },
      output: {
        docNumber: {
          $documentNumber: { }
        }
      }
    }
  },

  { $addFields: { result: { $add: ["$docNumber", page * 5] }}},

  // project final fields
  { $project: {
      question: 1,
      //result: 1,
      //number: 1,
      position: { $concat: [ { $toString: "$result" }, " of ", { $toString: "$totalCount" }]}
    }
  },
])
  
getLevelPageWithPosition(3);