我正在用Node.js和mongoose写一个web应用程序。如何对我从.find()调用得到的结果进行分页?我想要一个功能可比的“限制50,100”在SQL。


当前回答

以上回答是正确的。

只是一个插件,任何人谁是异步等待而不是 承诺! !

const findAllFoo = async (req, resp, next) => {
    const pageSize = 10;
    const currentPage = 1;

    try {
        const foos = await FooModel.find() // find all documents
            .skip(pageSize * (currentPage - 1)) // we will not retrieve all records, but will skip first 'n' records
            .limit(pageSize); // will limit/restrict the number of records to display

        const numberOfFoos = await FooModel.countDocuments(); // count the number of records for that model

        resp.setHeader('max-records', numberOfFoos);
        resp.status(200).json(foos);

    } catch (err) {
        resp.status(500).json({
            message: err
        });
    }
};

其他回答

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

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

MyModel.find(query, fields, { skip: 10, limit: 5 }, function(err, results) { ... });
app.get("/:page",(req,res)=>{
        post.find({}).then((data)=>{
            let per_page = 5;
            let num_page = Number(req.params.page);
            let max_pages = Math.ceil(data.length/per_page);
            if(num_page == 0 || num_page > max_pages){
                res.render('404');
            }else{
                let starting = per_page*(num_page-1)
                let ending = per_page+starting
                res.render('posts', {posts:data.slice(starting,ending), pages: max_pages, current_page: num_page});
            }
        });
});

最好的方法(IMO)是在有限的集合或文档中使用跳过和限制BUT。

要在有限的文档中进行查询,可以使用特定的索引,例如DATE类型字段上的索引。见下图

let page = ctx.request.body.page || 1
let size = ctx.request.body.size || 10
let DATE_FROM = ctx.request.body.date_from
let DATE_TO = ctx.request.body.date_to

var start = (parseInt(page) - 1) * parseInt(size)

let result = await Model.find({ created_at: { $lte: DATE_FROM, $gte: DATE_TO } })
    .sort({ _id: -1 })
    .select('<fields>')
    .skip( start )
    .limit( size )        
    .exec(callback)

以上回答是正确的。

只是一个插件,任何人谁是异步等待而不是 承诺! !

const findAllFoo = async (req, resp, next) => {
    const pageSize = 10;
    const currentPage = 1;

    try {
        const foos = await FooModel.find() // find all documents
            .skip(pageSize * (currentPage - 1)) // we will not retrieve all records, but will skip first 'n' records
            .limit(pageSize); // will limit/restrict the number of records to display

        const numberOfFoos = await FooModel.countDocuments(); // count the number of records for that model

        resp.setHeader('max-records', numberOfFoos);
        resp.status(200).json(foos);

    } catch (err) {
        resp.status(500).json({
            message: err
        });
    }
};