11

I want to make a pagination feature in my Collection. How can find a documents with 'start' and 'limit' positions and get total document number in a single query?

Erik
  • 14,060
  • 49
  • 132
  • 218

6 Answers6

19

You can't get both results in one query; the best you can do is to get them both using one Mongoose Query object:

var query = MyModel.find({});
query.count(function(err, count) {...});
query.skip(5).limit(10).exec('find', function(err, items) {...});

Use a flow control framework like async to cleanly execute them in parallel if needed.

JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • 1
    When I run this the exec in the second query returns the same as the count... Does the count function modify the original query?? – Zeke Nierenberg Oct 13 '13 at 16:52
  • 1
    @ZekeAlexandreNierenberg You're right, Zeke; that must have changed as some point. I updated the example to add the `'find'` parameter to the `exec` call to make it work with Mongoose 3.6.20. – JohnnyHK Oct 13 '13 at 17:01
10

You can use the plugin Mongoose Paginate:

$ npm install mongoose-paginate

After in your routes or controller, just add :

Model.paginate({}, { page: 3, limit: 10 }, function(err, result) {
    // result.docs 
    // result.total 
    // result.limit - 10 
    // result.page - 3 
    // result.pages 
});
Yosvel Quintero
  • 18,669
  • 5
  • 37
  • 46
4

If you plan to have a lot of pages, you should not use skip/limit, but rather calculate ranges.

See Scott's answer for a similar question: MongoDB - paging

Community
  • 1
  • 1
Eve Freeman
  • 32,467
  • 4
  • 86
  • 101
1

UPDATE :

Using skip and limit is not good for pagination. Here is the discussion over it.

@Wes Freeman, Gave a good answer. I read the linked pose, you should use range query. n = 0; i = n+10; db.students.find({ "id" : { $gt: n, $lt: (n+i)} } );

OLD ANSWER (don't use this)

use something like

n = db.students.find().skip(n).limit(10);
//pass n dynamically, so for page 1 it should be 0 , page 2 it should be 10 etc

more documentation at http://www.mongodb.org/display/DOCS/Advanced+Queries

Community
  • 1
  • 1
Hitesh Joshi
  • 724
  • 8
  • 19
  • Thanks for the reply, but need need to get total document count. – Erik Sep 22 '12 at 11:13
  • total = db.students.find().count() – Hitesh Joshi Sep 23 '12 at 02:47
  • Wes Freeman, Gave a good answer. I read the linked pose, you should use range query. n = 0; i = n+10; db.students.find({ "id" : { $gt: n, $lt: (n+i)} } ); – Hitesh Joshi Sep 23 '12 at 02:50
  • 3
    As jackalope points out in one of the answers to that post, the calculated range strategy falls apart if you have a lot of sorting options or if what you're sorting on allows duplicates. It just depends on the situation. – JohnnyHK Sep 23 '12 at 04:10
0
   user.find({_id:{$nin:friends_id},_id:{$ne:userId}},function(err,user_details){
    if (err)
    res.send(err);
    response ={
        statusCode:200,
        status:true,
        values:user_details
    }
    res.json(response);
   }).skip(10).limit(1);
RBJT
  • 1
  • 3
    Your answer can be the correct one, but please try to add more context, to your code to help everyone that might be looking for the same. Please refer to [How do I write a good answer?](https://stackoverflow.com/help/how-to-answer) – rmjoia Oct 24 '17 at 06:28
  • Please explain what the code in your answer does so people with low knowledge in the involved technologies have a chance to understand and re-use it. – Mathieu VIALES Oct 24 '17 at 06:52
0

I am using this function,

You can check if prev and next data is available or not.

async (req, res) => {
let { page = 1, size = 10 } = req.query
page = parseInt(page)
size = parseInt(size)
const query = {}
const totalData = await Model.find().estimatedDocumentCount()
const data = await Model.find(query).skip((page - 1) * size).limit(size).exec()


const pageNumber = Math.ceil(totalData / size)
const results = {
    currentPage: page,
    prevPage: page <= 1 ? null : page - 1,
    nextPage: page >= pageNumber ? null : page + 1,
    data
}
res.json(results) }

To know more estimatedDocumentCount

Najmus Sakib
  • 447
  • 5
  • 14