MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

MongoDB - Рамка за агрегиране (Общ брой)

Има решение, използващо push и slice:https://stackoverflow.com/a/39784851/4752635 (@emaniacs го споменава и тук).

Но предпочитам да използвам 2 заявки. Решение с натискане на $$ROOT и използване на $slice се натъква на ограничение на паметта за документи от 16MB за големи колекции. Също така, за големи колекции две заявки заедно изглежда се изпълняват по-бързо от тази с натискане на $$ROOT. Можете да ги изпълнявате и паралелно, така че да сте ограничени само от по-бавната от двете заявки (вероятно тази, която сортира).

  1. Първо за филтриране и след това групиране по ID, за да получите брой филтрирани елементи. Не филтрирайте тук, не е необходимо.
  2. Втора заявка, която филтрира, сортира и пагинира.

Приех това решение, използвайки 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. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Много странен проблем с Mongoose/MongoDB при стартиране на MEAN сайт на Openshift

  2. Как да направя заявка за отделни стойности в Mongoose, но да върна целия документ?

  3. Правилно вмъкване на DateTime от c# към mongodb

  4. актуализиране на n-тия документ в документ с вложен масив в mongodb

  5. Защо PyMongo кодира uuid.uuid1() като BSON::Binary?