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

我正在用Node.js和猫鼬编写一个webapp。如何对.find()通话结果进行分页我想要一个与"LIMIT 50,100"SQL 相当的功能

凯西里2020/03/23 11:33:47

如果您使用猫鼬作为静态 API的来源,请查看“ restify-mongoose ”及其查询。它完全内置了此功能。

集合上的任何查询都提供了在这里有用的标题

test-01:~$ curl -s -D - localhost:3330/data?sort=-created -o /dev/null
HTTP/1.1 200 OK
link: </data?sort=-created&p=0>; rel="first", </data?sort=-created&p=1>; rel="next", </data?sort=-created&p=134715>; rel="last"
.....
Response-Time: 37

因此,基本上,您将获得具有相对线性加载时间的通用服务器,用于查询集合。如果您想进入自己的实现中,那真是太棒了。

飞云2020/03/23 11:33:46

您可以这样编写查询。

mySchema.find().skip((page-1)*per_page).limit(per_page).exec(function(err, articles) {
        if (err) {
            return res.status(400).send({
                message: err
            });
        } else {
            res.json(articles);
        }
    });

page:来自客户端的页码,作为请求参数。
per_page:每页显示的结果数

如果您使用的是MEAN堆栈,则以下博客文章提供了许多信息,这些信息可用于在前端使用angular-UI引导程序创建分页,并在后端使用猫鼬跳过和限制方法。

参见:https : //techpituwa.wordpress.com/2015/06/06/mean-js-pagination-with-angular-ui-bootstrap/

乐米亚2020/03/23 11:33:46

您可以使用skip()和limit(),但是效率很低。更好的解决方案是对索引字段加limit()进行排序。Wunderflats的我们在这里发布了一个小型库:https : //github.com/wunderflats/goosepage 它使用第一种方法。

西门Jim2020/03/23 11:33:46

简单而强大的分页解决方案

async getNextDocs(no_of_docs_required: number, last_doc_id?: string) {
    let docs

    if (!last_doc_id) {
        // get first 5 docs
        docs = await MySchema.find().sort({ _id: -1 }).limit(no_of_docs_required)
    }
    else {
        // get next 5 docs according to that last document id
        docs = await MySchema.find({_id: {$lt: last_doc_id}})
                                    .sort({ _id: -1 }).limit(no_of_docs_required)
    }
    return docs
}

last_doc_id:您获得的最后一个文档ID

no_of_docs_required:您要提取的文档数,即5、10、50等。

  1. 如果您不向last_doc_id方法提供,则将获得5份最新文档
  2. 如果提供了,last_doc_id那么您将获得接下来的5个文档。
古一十三2020/03/23 11:33:46

最简单,最快捷的方法是,使用objectId示例进行分页;

初始负载条件

condition = {limit:12, type:""};

从响应数据中获取第一个和最后一个ObjectId

页面下一个条件

condition = {limit:12, type:"next", firstId:"57762a4c875adce3c38c662d", lastId:"57762a4c875adce3c38c6615"};

页面下一个条件

condition = {limit:12, type:"next", firstId:"57762a4c875adce3c38c6645", lastId:"57762a4c875adce3c38c6675"};

在猫鼬

var condition = {};
    var sort = { _id: 1 };
    if (req.body.type == "next") {
        condition._id = { $gt: req.body.lastId };
    } else if (req.body.type == "prev") {
        sort = { _id: -1 };
        condition._id = { $lt: req.body.firstId };
    }

var query = Model.find(condition, {}, { sort: sort }).limit(req.body.limit);

query.exec(function(err, properties) {
        return res.json({ "result": result);
});
Itachi2020/03/23 11:33:46

您也可以使用以下代码行

per_page = parseInt(req.query.per_page) || 10
page_no = parseInt(req.query.page_no) || 1
var pagination = {
  limit: per_page ,
  skip:per_page * (page_no - 1)
}
users = await User.find({<CONDITION>}).limit(pagination.limit).skip(pagination.skip).exec()

该代码将在最新版本的mongo中工作

Gil2020/03/23 11:33:46

这是一个示例示例,您可以尝试一下,

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
      });
  });
 });
西里神奇2020/03/23 11:33:46

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

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

由于它将是a,因此String我们需要将其转换为a Number进行计算。让我们使用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);
    });

BTW 分页始于0

猪猪2020/03/23 11:33:46

在通过Rodolphe提供的信息仔细研究了Mongoose API之后,我想出了以下解决方案:

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