programing

결과를 제한하면 MongoDB가 생성되지만 여전히 전체 카운트를 얻을 수 있습니까?

padding 2023. 5. 18. 20:49
반응형

결과를 제한하면 MongoDB가 생성되지만 여전히 전체 카운트를 얻을 수 있습니까?

속도를 위해 쿼리를 10개의 결과로 제한하고 싶습니다.

db.collection.find( ... ).limit(10)

하지만 총 카운트도 알고 싶습니다. 즉, "124개였는데 10개밖에 없습니다."이것을 할 수 있는 좋은 효율적인 방법이 있습니까?

기본적으로,count()무시하는limit()전체 쿼리에서 결과를 카운트합니다.그래서 예를 들어 이렇게 하면,var a = db.collection.find(...).limit(10);입니다.a.count()쿼리의 총 개수가 표시됩니다.

실행 횟수(1)에는 제한 및 건너뛰기가 포함됩니다.

@johnnycrab이 허용하는 답변은 mongo CLI에 대한 것입니다.

Node.js와 Express.js에 동일한 코드를 작성해야 하는 경우 이를 사용해야 toArray의 "result"와 함께 "count" 기능을 사용할 수 있습니다.

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

    });

});

cursor.count()무시해야 합니다.cursor.skip()그리고.cursor.limit()결석으로

출처: http://docs.mongodb.org/manual/reference/method/cursor.count/ #dll.count

동일한 입력 문서 집합에서 단일 단계 내에서 여러 집계 파이프라인을 처리하는 단계를 사용할 수 있습니다.

// { item: "a" }
// { item: "b" }
// { item: "c" }
db.collection.aggregate([
  { $facet: {
    limit: [{ $limit: 2 }],
    total: [{ $count: "count" }]
  }},
  { $set: { total: { $first: "$total.count" } } }
])
// { limit: [{ item: "a" }, { item: "b" }], total: 3 }

이렇게 하면 동일한 쿼리 내에서 두 개의 문서를 모두 가져올 수 있습니다.limit: [{ $limit: 2 }]) 및 총 문서 수({ $count: "count" }).

결승전$set단계는 선택적인 정리 단계이며, 바로 거기에서 결과를 투영합니다.$count등의 무대"total" : [ { "count" : 3 } ]된다total: 3.

푸시 앤 슬라이스를 사용한 솔루션이 있습니다. https://stackoverflow.com/a/39784851/4752635

선호합니다

  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
            });
          }
      });
    }
  });
});

언급URL : https://stackoverflow.com/questions/15300882/limiting-results-in-mongodb-but-still-getting-the-full-count

반응형