2013-03-08 34 views

Trả lời

28

Theo mặc định, bỏ qua count()limit() và đếm kết quả trong toàn bộ truy vấn. Vì vậy, khi bạn làm ví dụ này, var a = db.collection.find(...).limit(10); chạy a.count() sẽ cung cấp cho bạn tổng số truy vấn của bạn.

19

Làm đếm (1) bao gồm giới hạn và bỏ qua.

+0

Tính đến mongoengine, 'Lỗi Loại: with_limit_and_skip phải là True hoặc False', đếm (Đúng) sẽ thực hiện công việc – kkzxak47

4

Câu trả lời được chấp nhận bởi @johnnycrab dành cho CLI mongo.

Nếu bạn phải viết cùng một mã trong Node.js và Express.js, bạn sẽ phải sử dụng nó như thế này để có thể sử dụng hàm "đếm" cùng với "kết quả" của toArray.

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

Sau đó, bạn có thể chạy hai chức năng sau nó như thế này (một lồng nhau trong khác)

curFind.count(function (e, count) { 

// Use count here 

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

    // Use result here and count here 

    }); 

}); 
0

Có một giải pháp sử dụng push và lát: https://stackoverflow.com/a/39784851/4752635

tôi prefe

  1. Đầu tiên để lọc và sau đó nhóm theo ID để nhận số lượng phần tử được lọc. Không lọc ở đây, nó là không cần thiết.
  2. Truy vấn thứ hai lọc, sắp xếp và phân loại.

Giải pháp với việc đẩy $$ ROOT và sử dụng $ slice chạy vào giới hạn bộ nhớ tài liệu 16MB cho các bộ sưu tập lớn. Ngoài ra, đối với các bộ sưu tập lớn, hai truy vấn cùng nhau dường như chạy nhanh hơn so với một bộ lọc có ROOT $ đẩy. Bạn có thể chạy chúng song song là tốt, vì vậy bạn bị giới hạn bởi chậm hơn của hai truy vấn (có thể là một trong những loại đó).

tôi đã giải quyết với giải pháp này sử dụng 2 truy vấn và khuôn khổ hợp (lưu ý - Tôi sử dụng Node.js trong ví dụ này, nhưng ý tưởng là như nhau):

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

Vui lòng không thêm [cùng câu trả lời] (http://stackoverflow.com/a/42143423/4687348) vào nhiều câu hỏi. Trả lời câu trả lời hay nhất và gắn cờ phần còn lại là trùng lặp. Xem [Có thể chấp nhận thêm câu trả lời trùng lặp cho một số câu hỏi không?] (Http://meta.stackexchange.com/q/104227/347985) – FelixSFD

Các vấn đề liên quan