Mongoose Pagination

Have a Database Problem? Speak with an Expert for Free
Get Started >>

Introduction

Pagination is a process in which a document is divided into discrete pages. In simple words, if we have a document containing a large amount of data, and we wish not to print all of it in once, we divide this data into “pages”. These pages contain data according to the limit specified. In this article, we will discuss how to do pagination in mongoose.

For example, say there is a collection containing one hundred documents. And the client is requesting these documents. Should we send all one hundred document at once? No! it is not a good idea. Instead, we paginate it. Say, we send ten documents per request. This is called pagination. Let’s discuss pagination in mongoose.

Pagination in mongoose

I have created a collection, named details, that contains twenty documents.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> db.details.find()
{ "_id" : ObjectId("5da0cbc9ff01c8ec07f65040"), "name" : "John" }
{ "_id" : ObjectId("5da0cbcfff01c8ec07f65041"), "name" : "Joe" }
{ "_id" : ObjectId("5da0cbd3ff01c8ec07f65042"), "name" : "Joey" }
{ "_id" : ObjectId("5da0cbd7ff01c8ec07f65043"), "name" : "Jose" }
{ "_id" : ObjectId("5da0cbddff01c8ec07f65044"), "name" : "Anna" }
{ "_id" : ObjectId("5da0cbe4ff01c8ec07f65045"), "name" : "Anto" }
{ "_id" : ObjectId("5da0cbebff01c8ec07f65046"), "name" : "Bob" }
{ "_id" : ObjectId("5da0cbeeff01c8ec07f65047"), "name" : "Bobby" }
{ "_id" : ObjectId("5da0cbf2ff01c8ec07f65048"), "name" : "Billy" }
{ "_id" : ObjectId("5da0cbf4ff01c8ec07f65049"), "name" : "Bill" }
{ "_id" : ObjectId("5da0cbf8ff01c8ec07f6504a"), "name" : "Ben" }
{ "_id" : ObjectId("5da0cbfbff01c8ec07f6504b"), "name" : "Lisa" }
{ "_id" : ObjectId("5da0cbfdff01c8ec07f6504c"), "name" : "Liss" }
{ "_id" : ObjectId("5da0cc01ff01c8ec07f6504d"), "name" : "Leena" }
{ "_id" : ObjectId("5da0cc05ff01c8ec07f6504e"), "name" : "Mike" }
{ "_id" : ObjectId("5da0cc08ff01c8ec07f6504f"), "name" : "Mikey" }
{ "_id" : ObjectId("5da0cc0bff01c8ec07f65050"), "name" : "Mendy" }
{ "_id" : ObjectId("5da0cc12ff01c8ec07f65051"), "name" : "Sam" }
{ "_id" : ObjectId("5da0cc14ff01c8ec07f65052"), "name" : "Sunny" }
{ "_id" : ObjectId("5da0cc1aff01c8ec07f65053"), "name" : "Sophie" }

We will divide this collection into four pages, each containing five documents. So let’s begin.

There are various options for pagination in mongoose. We can write the code ourselves or use any external library. Here, we will go with the second option. There are quite a few libraries for pagination. We will use “mongoose-aggregate-paginate-v2”.

Let’s install it.

1
npm install mongoose-aggregate-paginate-v2

The second step is, using this library in the file where we defined the schema. This is how my schema looks right now.

1
2
3
4
5
6
7
8
9
10
11
const mongoose = require("mongoose");

const Schema = mongoose.Schema;

let detail = new Schema({
  name: {
    type: String
  }
});

module.exports = mongoose.model("detail", detail);

First, we need to import it in this file.

1
var aggregatePaginate = require("mongoose-aggregate-paginate-v2");

Then, we need to tell mongoose that we are going to use this library with our schema.

1
detail.plugin(aggregatePaginate);

Now, this is how the model looks like.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const mongoose = require("mongoose");

const Schema = mongoose.Schema;

var aggregatePaginate = require("mongoose-aggregate-paginate-v2"); //first step

let detail = new Schema({
  name: {
    type: String
  }
});

detail.plugin(aggregatePaginate); //second step

module.exports = mongoose.model("detail", detail);

The model is ready! Let’s create the route handler.

1
router.route("/paginationdemo").get(function(req, res) {});

This is the route handler in which we will write the code for pagination. We will be using the postman tool for testing this route. You can download this tool from www.getpostman.com.

We will use the aggregatePaginate() method of the library we just installed. This method has three parameters – the aggregate query, options, and a callback function. The second parameter will decide how pagination will work.

We have to pass an object as the second parameter. This object contains two properties – page and limit.

page: It specifies the page that will be returned limit: It specifies the number of documents per page.

It looks something like this.

1
2
3
4
{
        page: 3,
        limit: 5
    }

This means, the third page will be returned and every page will contain as much as five documents.

The first parameter is the aggregate query.

1
var aggregateQuery = detail.aggregate();

And the third parameter is a callback function. This function has two parameters – an error (if any occurs) and the returning value.

Let’s put all of this at work.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
router.route("/paginationdemo").get(function(req, res) {
  var aggregateQuery = detail.aggregate();

  detail.aggregatePaginate(myAggregate, { page: 3, limit: 5 }, function(
    err,
    result
  ) {
    if (err) {
      console.err(err);
    } else {
      res.json(result);
    }
  });
});

Let’s execute this route using the postman tool and see what is the output.

Image from Gyazo

It returns an array of objects. Let’s discuss what all of these fields denote.

docs: the array of objects(documents) totalDocs: total number of documents in the collection limit: limit per page we specified page: current page totalPages: total number of pages after pagination pagingCounter: serial number of the first document hasPrevPage: true if there exists a previous page, else false hasNextPage: true if there exists a next page, else false prevPage: total number of previous pages nextPage: total number of pages ahead.

Conclusion

This is how we use pagination in mongoose. As mentioned earlier, there are various ways for pagination, and according to us, this is one the easiest and simple way. The object returned contains a lot of information and this information is very efficient while working with the client-side.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.