2016-01-22 190 views
2

我有一個包含許多對象的json數據。我想限制分頁的數據,我需要總項目數。請幫忙。獲取總數與貓鼬查詢跳過&限制

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

我想要計數和跳過的數據作爲迴應。

+0

的可能的複製[貓鼬限/偏移和計數查詢](http://stackoverflow.com/questions/13935733/mongoose-limit-offset-and-count-query) – chridam

回答

0

您需要執行2個查詢才能做到這一點。一個獲得結果,另一個獲得總項目金額爲.count()

例如,您可以在「paginator」上看到貓鼬mongoose-paginate的示例代碼。

+0

我可以在單個API調用中做到這一點嗎?@Alexy B – govind

7

您可以使用異步庫一次運行2個查詢。在你的情況下,你可以運行一個查詢來獲取文檔數量,另一個查詢分頁。

實施例與「用戶」模式:

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

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

    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]}); 

    }); 

異步可以運行一個數量根據要使用的硬件並行查詢。這比使用2個獨立查詢來計算並獲取所需的文檔要快。 希望這有助於。

+0

很好的答案,謝謝。更清潔,更快。 – stackers

2

這些解決方案的問題在於,對於每個請求,您都在執行兩個查詢。當性能成爲問題時,如果您有複雜的數據結構和大型數據集,這會變得有問題。請考慮創建一個特殊功能,用於偵聽/resource?count=true/resource/count GET方法並僅返回計數。

-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 
       }); 
      }