2013-03-08 16 views

Odpowiedz

28

Domyślnie count() ignoruje limit() i zlicza wyniki w całym zapytaniu. Kiedy to zrobisz, var a = db.collection.find(...).limit(10); z numerem a.count() otrzymasz całkowitą liczbę zapytań.

19

Doing count (1) zawiera limit i pomiń.

+0

Od mongoengine, 'TypeError: with_limit_and_skip musi być True or False', count (True) wykona pracę – kkzxak47

4

Przyjęta odpowiedź @johnnycrab dotyczy interfejsu CLI mongo.

Jeśli musisz napisać ten sam kod w Node.js i Express.js, będziesz musiał użyć go w ten sposób, aby móc używać funkcji "count" wraz z "wynikiem" toArray.

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

Następnie można uruchomić dwie funkcje po nim tak (jeden zagnieżdżony w drugim)

curFind.count(function (e, count) { 

// Use count here 

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

    // Use result here and count here 

    }); 

}); 
0

Istnieje rozwiązanie używając pchają i kawałek: https://stackoverflow.com/a/39784851/4752635

I prefe

  1. Najpierw do filtrowania, a następnie grupowania według identyfikatora, aby uzyskać liczbę filtrowanych elementów. Nie filtruj tutaj, nie jest to konieczne.
  2. Druga kwerenda, która filtruje, sortuje i stronicuje.

Rozwiązanie z naciśnięciem $$ ROOT i użyciem $ slice uruchamia ograniczenie pamięci do dokumentów o 16 MB dla dużych zbiorów. Również w przypadku dużych kolekcji dwa zapytania razem wydają się działać szybciej niż w przypadku przepychania $$ ROOT. Możesz je uruchamiać równolegle, więc ogranicza Cię tylko wolniejszy z dwóch zapytań (prawdopodobnie ten, który sortuje).

mam rozliczane z tego rozwiązania przy użyciu 2 zapytań i ramy Agregacja (Uwaga - używam node.js w tym przykładzie, ale idea jest taka sama):

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

Proszę nie dodawać [tej samej odpowiedzi] (http://stackoverflow.com/a/42143423/4687348) do wielu pytań. Odpowiedz na najlepszą i oznacz flagę jako duplikaty. Zobacz [Czy dopuszczalne jest dodanie duplikowanej odpowiedzi na kilka pytań?] (Http://meta.stackexchange.com/q/104227/347985) – FelixSFD

Powiązane problemy