获取总计数以及Mongoose Query skip& LIMT

时间:2016-01-22 11:20:39

标签: node.js database mongodb mongoose aggregation-framework

我有一个包含许多对象的json数据。我想限制分页数据,我需要总项数。请帮忙。

Model.find().skip((pageNumber-1)*limit).limit(limit).exec()

我想要计数并跳过数据作为回应。

5 个答案:

答案 0 :(得分:12)

您可以使用异步库一次运行2个查询。在您的情况下,您可以运行一个查询来获取文档数量,另一个查询用于分页。

'用户'的示例模型:

    var async = require('async');
    var User = require('./models/user');

    var countQuery = function(callback){
         User.count({}, function(err, count){
               if(err){ callback(err, null) }
               else{
                   callback(null, count);
                }
         }
    };

    var retrieveQuery = function(callback){
        User.find({}).skip((page-1)*PAGE_LIMIT)
                     .limit(PAGE_LIMIT)
                     .exec(function(err, doc){
                            if(err){ callback(err, null) }
                            else{
                            callback(null, doc);
                            }
                      }
    };

    async.parallel([countQuery, retrieveQuery], function(err, results){
         //err contains the array of error of all the functions
         //results contains an array of all the results
         //results[0] will contain value of doc.length from countQuery function
         //results[1] will contain doc of retrieveQuery function
         //You can send the results as

         res.json({users: results[1], pageLimit: PAGE_LIMIT, page: page, totalCount: results[0]});

    });

async允许您并行运行多个查询,具体取决于您使用的硬件。这比使用2个独立查询来获取计数并获取所需文档更快。 希望这会有所帮助。

答案 1 :(得分:3)

您需要执行2次查询才能实现这一目标。一个用于获得结果,另一个用于获得.count()的总项目金额。

例如,您可以在" paginator"上观看的代码对于猫鼬mongoose-paginate

答案 2 :(得分:2)

这些解决方案的问题在于,对于每个请求,您正在进行两次查询。当您拥有复杂的数据结构和大型数据集时,这会成为一个问题。请考虑创建一个特殊的函数来侦听/resource?count=true/resource/count GET方法并仅返回计数。

答案 3 :(得分:2)

在猫鼬v3 +中,我已经通过$facetaggregate解决了以下问题:

const [{ paginatedResult, [{ totalCount }] }] = await Model.aggregate([{
  $facet: {
    paginatedResult: [
      { $match: query },
      { $skip: skip },
      { $limit: limit }
    ],
    totalCount: [
      { $match: query },
      { $count: 'totalCount' }
    ]
  }
}])

其中totalCount是指与搜索查询匹配的记录总数,而paginatedResult只是它们的分页片段。

答案 4 :(得分:-1)

要仅执行一个查询,您可以使用与promises和数组切片关联的find()方法。一个小例子是:

getPaginated(query, skip, limit){
       return this.model.find(query)
            .lean()
            .then((value)=>{
                if (value.length === 0) return {userMessage: 'Document not found'};
                const count = value.length;

                //skip===0 must be handled
                const start = parseInt(limit)*parseInt(skip - 1);
                const end = start + parseInt(reqQuery.pagesize);

                //slicing the array
                value = value.slice(start,end);

                //could return it another way...
                value.push( { 'querySize': count });
                return value;
              })
              .catch((reason)=>{
                //...handling code
              });
          }