如何在 Node.js 中使用 Mongoose 进行分页?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5539955/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:59:50  来源:igfitidea点击:

How to paginate with Mongoose in Node.js?

mongodbnode.jspaginationmongoose

提问by Thomas

I am writing a webapp with Node.js and mongoose. How can I paginate the results I get from a .find()call? I would like a functionality comparable to "LIMIT 50,100"in SQL.

我正在用 Node.js 和 mongoose 编写一个 web 应用程序。如何对从.find()通话中获得的结果进行分页?我想要一个类似于"LIMIT 50,100"SQL的功能。

采纳答案by Thomas

After taking a closer look at the Mongoose API with the information provided by Rodolphe, I figured out this solution:

在使用 Rodolphe 提供的信息仔细查看 Mongoose API 后,我想出了这个解决方案:

MyModel.find(query, fields, { skip: 10, limit: 5 }, function(err, results) { ... });

回答by Chris Hinkle

I'm am very disappointed by the accepted answers in this question. This will not scale. If you read the fine print on cursor.skip( ):

我对这个问题中接受的答案感到非常失望。这不会扩展。如果您阅读了 cursor.skip() 上的细则:

The cursor.skip() method is often expensive because it requires the server to walk from the beginning of the collection or index to get the offset or skip position before beginning to return result. As offset (e.g. pageNumber above) increases, cursor.skip() will become slower and more CPU intensive. With larger collections, cursor.skip() may become IO bound.

cursor.skip() 方法通常很昂贵,因为它要求服务器在开始返回结果之前从集合或索引的开头开始获取偏移量或跳过位置。随着偏移量(例如上面的 pageNumber)的增加,cursor.skip() 将变得更慢并且更占用 CPU。对于较大的集合, cursor.skip() 可能会成为 IO 绑定。

To achieve pagination in a scaleable way combine a limit( ) along with at least one filter criterion, a createdOn date suits many purposes.

为了以可缩放的方式实现分页,结合 limit() 和至少一个过滤条件,createdOn 日期适合多种用途。

MyModel.find( { createdOn: { $lte: request.createdOnBefore } } )
.limit( 10 )
.sort( '-createdOn' )

回答by Madhusudhan

Pagination using mongoose, express and jade - Here's a link to my blog with more detail

使用 mongoose、express 和 jade 进行分页 -这是我博客的链接,其中包含更多详细信息

var perPage = 10
  , page = Math.max(0, req.param('page'))

Event.find()
    .select('name')
    .limit(perPage)
    .skip(perPage * page)
    .sort({
        name: 'asc'
    })
    .exec(function(err, events) {
        Event.count().exec(function(err, count) {
            res.render('events', {
                events: events,
                page: page,
                pages: count / perPage
            })
        })
    })

回答by Rodolphe

You can chain just like that:

你可以像这样链接:

var query = Model.find().sort('mykey', 1).skip(2).limit(5)

Execute the query using exec

使用执行查询 exec

query.exec(callback);

回答by CENT1PEDE

In this case, you can add the query pageand/ or limitto your URL as a query string.

在这种情况下,您可以将查询page和/或limit作为查询字符串添加到您的 URL。

For example:
?page=0&limit=25 // this would be added onto your URL: http:localhost:5000?page=0&limit=25

例如:
?page=0&limit=25 // this would be added onto your URL: http:localhost:5000?page=0&limit=25

Since it would be a Stringwe need to convert it to a Numberfor our calculations. Let's do it using the parseIntmethod and let's also provide some default values.

由于它将是 aString我们需要将其转换为 aNumber以进行计算。让我们使用parseInt方法来做,让我们也提供一些默认值。

const pageOptions = {
    page: parseInt(req.query.page, 10) || 0,
    limit: parseInt(req.query.limit, 10) || 10
}

sexyModel.find()
    .skip(pageOptions.page * pageOptions.limit)
    .limit(pageOptions.limit)
    .exec(function (err, doc) {
        if(err) { res.status(500).json(err); return; };
        res.status(200).json(doc);
    });

BTWPagination starts with 0

BTW分页开始于0

回答by Clément Renaud

You can use a little package called Mongoose Paginatethat makes it easier.

你可以使用一个叫做Mongoose Paginate 的小包,让它更容易。

$ npm install mongoose-paginate

After in your routes or controller, just add :

在您的路线或控制器之后,只需添加:

/**
 * querying for `all` {} items in `MyModel`
 * paginating by second page, 10 items per page (10 results, page 2)
 **/

MyModel.paginate({}, 2, 10, function(error, pageCount, paginatedResults) {
  if (error) {
    console.error(error);
  } else {
    console.log('Pages:', pageCount);
    console.log(paginatedResults);
  }
}

回答by Libu Mathew

This is a sample example you can try this,

这是您可以尝试的示例示例,

var _pageNumber = 2,
  _pageSize = 50;

Student.count({},function(err,count){
  Student.find({}, null, {
    sort: {
      Name: 1
    }
  }).skip(_pageNumber > 0 ? ((_pageNumber - 1) * _pageSize) : 0).limit(_pageSize).exec(function(err, docs) {
    if (err)
      res.json(err);
    else
      res.json({
        "TotalCount": count,
        "_Array": docs
      });
  });
 });

回答by PayPal_Kartik

Try using mongoose function for pagination. Limit is the number of records per page and number of the page.

尝试使用 mongoose 函数进行分页。限制是每页的记录数和页数。

var limit = parseInt(body.limit);
var skip = (parseInt(body.page)-1) * parseInt(limit);

 db.Rankings.find({})
            .sort('-id')
            .limit(limit)
            .skip(skip)
            .exec(function(err,wins){
 });

回答by Indra Santosa

This is what I done it on code

这是我在代码上所做的

var paginate = 20;
var page = pageNumber;
MySchema.find({}).sort('mykey', 1).skip((pageNumber-1)*paginate).limit(paginate)
    .exec(function(err, result) {
        // Write some stuff here
    });

That is how I done it.

我就是这样做的。

回答by kberg

Here is a version that I attach to all my models. It depends on underscore for convenience and async for performance. The opts allows for field selection and sorting using the mongoose syntax.

这是我附加到所有模型的版本。它依赖于下划线的方便和异步的性能。opts 允许使用 mongoose 语法进行字段选择和排序。

var _ = require('underscore');
var async = require('async');

function findPaginated(filter, opts, cb) {
  var defaults = {skip : 0, limit : 10};
  opts = _.extend({}, defaults, opts);

  filter = _.extend({}, filter);

  var cntQry = this.find(filter);
  var qry = this.find(filter);

  if (opts.sort) {
    qry = qry.sort(opts.sort);
  }
  if (opts.fields) {
    qry = qry.select(opts.fields);
  }

  qry = qry.limit(opts.limit).skip(opts.skip);

  async.parallel(
    [
      function (cb) {
        cntQry.count(cb);
      },
      function (cb) {
        qry.exec(cb);
      }
    ],
    function (err, results) {
      if (err) return cb(err);
      var count = 0, ret = [];

      _.each(results, function (r) {
        if (typeof(r) == 'number') {
          count = r;
        } else if (typeof(r) != 'number') {
          ret = r;
        }
      });

      cb(null, {totalCount : count, results : ret});
    }
  );

  return qry;
}

Attach it to your model schema.

将其附加到您的模型架构。

MySchema.statics.findPaginated = findPaginated;