UFO ET IT

몽구스 제한 / 오프셋 및 개수 쿼리

ufoet 2020. 11. 14. 11:25
반응형

몽구스 제한 / 오프셋 및 개수 쿼리


쿼리 성능에 대한 약간의 이상한 점 ... 총 문서 수를 수행하는 쿼리를 실행하고 제한 및 오프셋 가능한 결과 집합을 반환 할 수도 있습니다.

그래서 총 57 개의 문서가 있고 사용자는 10 개의 문서를 20으로 오프셋하기를 원합니다.

이 작업을 수행하는 두 가지 방법을 생각할 수 있습니다. 먼저 57 개 문서 (배열로 반환 됨)를 모두 쿼리 한 다음 array.slice를 사용하여 원하는 문서를 반환합니다. 두 번째 옵션은 mongo의 기본 'count'메소드를 사용하여 두 번째 쿼리를 실행 한 다음 mongo의 기본 $ limit 및 $ skip 집계자를 사용하여 두 번째 쿼리를 실행하는 것입니다.

어느 것이 더 잘 확장 될 것이라고 생각하십니까? 모든 것을 하나의 쿼리로 수행하거나 두 개의 개별 쿼리를 실행합니까?

편집하다:

// 1 query
var limit = 10;
var offset = 20;

Animals.find({}, function (err, animals) {
    if (err) {
        return next(err);
    }

    res.send({count: animals.length, animals: animals.slice(offset, limit + offset)});
});


// 2 queries
Animals.find({}, {limit:10, skip:20} function (err, animals) {            
    if (err) {
        return next(err);
    }

    Animals.count({}, function (err, count) {
        if (err) {
            return next(err);
        }

        res.send({count: count, animals: animals});
    });
});

두 가지 쿼리를 사용하는 것이 좋습니다.

  1. db.collection.count()총 항목 수를 반환합니다. 이 값은 Mongo의 어딘가에 저장되며 계산되지 않습니다.

  2. db.collection.find().skip(20).limit(10)여기에서는 일부 필드별로 정렬을 사용할 수 있다고 가정하므로이 필드에 색인을 추가하는 것을 잊지 마십시오. 이 쿼리도 빠릅니다.

모든 항목을 쿼리하지 않고 건너 뛰고 가져가는 것보다 나중에 빅 데이터가 있으면 데이터 전송 및 처리에 문제가 생길 수 있다고 생각합니다.


2 개의 쿼리를 사용하는 대신 단일 쿼리에서 집계 사용

집계 "$ facet" 는 더 빨리 가져올 수 있으며 총 개수데이터 건너 뛰기 및 제한

    db.collection.aggregate([

      //{$sort: {...}}

      //{$match:{...}}

      {$facet:{

        "stage1" : [ $group:{_id:null, count:{$sum:1}} ],

        "stage2" : [ { "$skip": 0}, {"$limit": 2} ]

      }},


     {$unwind: "$stage1"},

      //output projection
     {$project:{
        count: "$stage1.count",
        data: "$stage2"
     }}

 ]);

다음과 같이 출력 :-

[{
     count: 50,
     data: [
        {...},
        {...}
      ]
 }]

이 문제를 직접 해결 한 후 user854301의 답변을 기반으로 작성하고 싶습니다.

Mongoose ^4.13.8 I was able to use a function called toConstructor() which allowed me to avoid building the query multiple times when filters are applied. I know this function is available in older versions too but you'll have to check the Mongoose docs to confirm this.

The following uses Bluebird promises:

let schema = Query.find({ name: 'bloggs', age: { $gt: 30 } });

// save the query as a 'template'
let query = schema.toConstructor();

return Promise.join(
    schema.count().exec(),
    query().limit(limit).skip(skip).exec(),

    function (total, data) {
        return { data: data, total: total }
    }
);

Now the count query will return the total records it matched and the data returned will be a subset of the total records.

Please note the () around query() which constructs the query.

참고URL : https://stackoverflow.com/questions/13935733/mongoose-limit-offset-and-count-query

반응형