2013-03-08 40 views

回答

28

默認情況下,count()忽略limit()並計算整個查詢的結果。 因此,當你舉例這樣做,var a = db.collection.find(...).limit(10); 運行a.count()會給你你的查詢的總數。

19

做數(1)包括限制和跳過。

+0

由於mongoengine的, '類型錯誤:with_limit_and_skip必須是True或False, count(True)會做這項工作 – kkzxak47 2017-09-14 05:57:34

4

@johnnycrab接受的答案是mongo CLI。

如果您必須在Node.js和Express.js中編寫相同的代碼,您必須像這樣使用它,以便能夠使用「count」函數以及toArray的「結果」。

var curFind = db.collection('tasks').find({query}); 

然後你可以運行後,兩個函數像這樣(嵌套在另一個)

curFind.count(function (e, count) { 

// Use count here 

    curFind.skip(0).limit(10).toArray(function(err, result) { 

    // Use result here and count here 

    }); 

}); 
0

有使用推和切片的解決方案:https://stackoverflow.com/a/39784851/4752635

我prefe

  1. 首先進行篩選,然後按ID進行分組以獲得過濾元素的數量。不要在這裏過濾,這是沒有必要的。
  2. 第二個查詢過濾,排序和分頁。

推送$$ ROOT並使用$ slice的解決方案會導致大型集合的文檔內存限制爲16MB。此外,對於大型集合,兩個查詢的運行速度似乎比具有$$ ROOT推送速度的運行速度更快。你也可以並行地運行它們,所以你只能受限於兩個查詢中較慢的一個(可能是那個排序的)。

我已經使用2個查詢和聚合框架這一解決方案解決(注意 - 我用Node.js的這個例子,但思路是一樣的):

var aggregation = [ 
    { 
    // If you can match fields at the begining, match as many as early as possible. 
    $match: {...} 
    }, 
    { 
    // Projection. 
    $project: {...} 
    }, 
    { 
    // Some things you can match only after projection or grouping, so do it now. 
    $match: {...} 
    } 
]; 


// Copy filtering elements from the pipeline - this is the same for both counting number of fileter elements and for pagination queries. 
var aggregationPaginated = aggregation.slice(0); 

// Count filtered elements. 
aggregation.push(
    { 
    $group: { 
     _id: null, 
     count: { $sum: 1 } 
    } 
    } 
); 

// Sort in pagination query. 
aggregationPaginated.push(
    { 
    $sort: sorting 
    } 
); 

// Paginate. 
aggregationPaginated.push(
    { 
    $limit: skip + length 
    }, 
    { 
    $skip: skip 
    } 
); 

// I use mongoose. 

// Get total count. 
model.count(function(errCount, totalCount) { 
    // Count filtered. 
    model.aggregate(aggregation) 
    .allowDiskUse(true) 
    .exec(
    function(errFind, documents) { 
    if (errFind) { 
     // Errors. 
     res.status(503); 
     return res.json({ 
     'success': false, 
     'response': 'err_counting' 
     }); 
    } 
    else { 
     // Number of filtered elements. 
     var numFiltered = documents[0].count; 

     // Filter, sort and pagiante. 
     model.request.aggregate(aggregationPaginated) 
     .allowDiskUse(true) 
     .exec(
     function(errFindP, documentsP) { 
      if (errFindP) { 
      // Errors. 
      res.status(503); 
      return res.json({ 
       'success': false, 
       'response': 'err_pagination' 
      }); 
      } 
      else { 
      return res.json({ 
       'success': true, 
       'recordsTotal': totalCount, 
       'recordsFiltered': numFiltered, 
       'response': documentsP 
      }); 
      } 
     }); 
    } 
    }); 
}); 
+1

請不要在多個問題中添加[相同的答案](http://stackoverflow.com/a/42143423/4687348)。回答最好的一個,並將其餘標記爲重複。請參閱[是否可以爲幾個問題添加重複答案?](http://meta.stackexchange.com/q/104227/347985) – FelixSFD 2017-02-09 17:47:39

相關問題