programing

페이지화를 위해 MongoDB 집계를 사용하는 방법은 무엇입니까?

batch 2023. 5. 21. 17:42
반응형

페이지화를 위해 MongoDB 집계를 사용하는 방법은 무엇입니까?

기본 페이지화를 수행하는 집계 쿼리를 수행합니다.

  1. 특정 주문에 속하는 모든 주문 찾기company_id
  2. 순서를 정렬합니다.order_number
  3. 총 문서 수 카운트
  4. 문서 번호 등으로 건너뜁니다.100그리고 나머지를 물려줍니다.
  5. 문서 수를 다음과 같이 제한합니다. 2그리고 그것들을 전달합니다.
  6. 문서에서 카운트와 선택한 몇 개의 필드를 반환하는 것으로 끝납니다.

다음은 쿼리에 대한 세부 정보입니다.

db.Order.collection.aggregate([

일치하는 모든 문서를 찾습니다.

  { '$match'    : { "company_id" : ObjectId("54c0...") } },

이렇게 하면 문서가 정렬됩니다.

  { '$sort'     : { 'order_number' : -1 } },

이렇게 하면 문서가 카운트되고 수정되지 않은 문서가 전달되지만, 여기서부터는 상황이 이상하게 변하기 때문에 잘못된 것이 분명합니다.

  {
    '$group' : {
      '_id'     : null,
      'count'   : { '$sum' : 1 },
      'entries' : { '$push' : "$$ROOT" }
    }
  },

일부 문서를 건너뛰는 것 같습니다.

  { "$skip"     : 100 },

이렇게 하면 문서가 제한되지만 다음과 같은 제한은 없습니다.

  { "$limit"    : 2 },

그러면 카운트가 반환되지만 배열에 있는 문서가 반환되지 않고 각 필드가 있는 배열이 반환됩니다.

  { '$project'  : {
      'count'     : 1,
      'entries'   : {'_id' : "$entries._id", 'order_number' : "$entries.order_number"}
    }
  }
])

결과는 다음과 같습니다.

[
  { "_id" : null,
    "count" : 300,
    "entries" : [
      {
        "_id" : [ObjectId('5a5c...'), ObjectId('5a5c...')],
        "order_number" : ["4346", "4345"]
      },
      {
        "_id" : [ObjectId('5a5c...'), ObjectId('5a5c...')],
        "order_number" : ["4346", "4345"]
      },
      ...
    ]
  }
]

어디서 틀립니까?

합계를 계산하고 부분 집합을 반환하려면 그룹화 및 건너뛰기/제한을 동일한 데이터 집합에 적용해야 합니다.이를 위해 패싯을 사용할 수 있습니다.

예를 들어, 세 번째 페이지를 표시하려면 페이지당 10개의 문서:

db.Order.aggregate([
    { '$match'    : { "company_id" : ObjectId("54c0...") } },
    { '$sort'     : { 'order_number' : -1 } },
    { '$facet'    : {
        metadata: [ { $count: "total" }, { $addFields: { page: NumberInt(3) } } ],
        data: [ { $skip: 20 }, { $limit: 10 } ] // add projection here wish you re-shape the docs
    } }
] )

두 개의 필드가 있는 단일 문서가 반환됩니다.

{
    "metadata" : [ 
        {
            "total" : 300,
            "page" : 3
        }
    ],
    "data" : [ 
        {
            ... original document ...
        }, 
        {
            ... another document ...
        }, 
        {
            ... etc up to 10 docs ...
        }
    ]
}

mongoDB 버전 5.0 이후에는 다음과 같은 단점을 피할 수 있는 다른 옵션이 있습니다.$facet반환된 모든 문서를 하나의 큰 문서로 그룹화합니다.가장 큰 문제는 16M 크기의 문서라는 것입니다.사용.$setWindowFields에서는 이러한 문제를 방지할 수 있습니다.

db.Order.aggregate([
    {$match: {company_id: ObjectId("54c0...") } },
    {$sort: {order_number: -1 } },
    {$setWindowFields: {output: {totalCount: {$count: {}}}}}
    {$skip: 20 },
    {$limit: 10 } 
])

언급URL : https://stackoverflow.com/questions/48305624/how-to-use-mongodb-aggregation-for-pagination

반응형