sql >> Database >  >> NoSQL >> MongoDB

MongoDB - Aggregatieraamwerk (totaal aantal)

Er is een oplossing met push en slice:https://stackoverflow.com/a/39784851/4752635 (@emaniacs vermeldt het hier ook).

Maar ik gebruik liever 2 queries. Oplossing met het pushen van $$ROOT en het gebruik van $slice loopt tegen een documentgeheugenbeperking van 16 MB aan voor grote collecties. Ook voor grote collecties lijken twee queries samen sneller te lopen dan die met $$ROOT push. Je kunt ze ook parallel uitvoeren, dus je wordt alleen beperkt door de langzamere van de twee zoekopdrachten (waarschijnlijk degene die sorteert).

  1. Eerst voor filteren en vervolgens groeperen op ID om het aantal gefilterde elementen te krijgen. Filter hier niet, het is niet nodig.
  2. Tweede vraag welke filtert, sorteert en pagineert.

Ik heb met deze oplossing afgerekend met behulp van 2 query's en een aggregatieraamwerk (opmerking - ik gebruik node.js in dit voorbeeld):

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. Mongoimport gebruiken om csv . te importeren

  2. Gebruik het resultaat van de vorige zoekopdracht in een andere zoekopdracht in mongodb

  3. Hoe kan ingebedde mongodb de gegevens behouden bij het afsluiten van de applicatie?

  4. Hoe gegevensverlies bij serverstoringen te voorkomen met MongoDB op een enkele machine?