Gabriel
Gabriel

Reputation: 439

How to split mongodb query into result pages

I have learning application that only create users, manage sessions and delete users. The backend is in Node.js.

I have the query that retrieve the list of users

var userList = function ( page, callback ) {
  user.find({}, function ( err, doc ) {
    if (err) {
      callback (err);
    }
    callback ( doc );
  });
};

then I have the handler that send it back to the application

var userList = function ( req, res ) {
  var page = req.param.page;
  models.account.userList( page, function ( result ) {
  res.json ( 200, result );
  });
};

and on the client side I take the results and display them in a table on the browser.

What I want to accomplish, is to split the list into pages of... lets say... 10 users each. So using the parameter Page of the function userList I would expect to send the right answers:

Page1: results 0 to 9 page2: results 10 to 19 etc

I could do a loop to extract what I want, but I am sure that receive from the query the whole list of users to reprocess it on a loop to only extract 10 users is not the right approach, but I could not figure out what the right approach would be.

I have already googled, but did not find the answer what I wanted. Also quickly check MongoDB documentation.

As you can guess I am new at this.

Can you please help me guiding on the right approach for this simple task?

Thank you very much.

Using bduran code, I was able to do the pagination that I wanted. The code after the answer is:

var userList = function ( page, itemsPerPage, callback ) {
  user
  .find()
  .skip( (page - 1) * itemsPerPage )
  .limit ( itemsPerPage )
  .exec ( function ( err, doc ) {
    if (err) {
      //do something if err;
    }
    callback ( doc );
  });
};

Upvotes: 2

Views: 1872

Answers (1)

durum
durum

Reputation: 3404

The most easy and direct way to do this is with skip and query. You select pages of, for example, ten elements and then skip ten times that number per page. With this method you don't need to get all elements and if the query is sorted with and index is really fast:

user
.find()
.skip((page-1)*10)
.limit(10)
.exec(function(err, doc){
  /*Rest of the logic here*/
});

If you need to sort the results in a non-natural order (with .sort) you will need to create an index in the database to speed up and optimize the queries. You can do it with .ensureIndex. In the terminal put the query you use to do and you are done.

db.user.ensureIndex({ createdAt: -1 })

Upvotes: 2

Related Questions