MongoDB Aggregate 사용시 동적 연산 및 페이징 처리

2020. 4. 21. 22:24서버 프로그래밍

정렬 기준이 되는 값을 복잡한 조건에 의해 동적으로 생성해서 정렬하고자 할 경우에는 $let, $cond, $eq 등의 명령을 이용하여 연산을 하고, 연산된 값을 기준으로 정렬을 시킬 수 있다.

db.sales.aggregate( [
   {
      $project: {
         finalTotal: {
            $let: {
               vars: {
                  total: { $add: [ '$price', '$tax' ] },
                  discounted: { $cond: { if: '$applyDiscount', then: 0.9, else: 1 } }
               },
               in: { $multiply: [ "$$total", "$$discounted" ] }
            }
         }
      }
   }
] )

https://docs.mongodb.com/manual/reference/operator/aggregation/let/

 

$let (aggregation) — MongoDB Manual

Behavior $let can access variables defined outside its expression block, including system variables. If you modify the values of externally defined variables in the vars block, the new values take effect only in the in expression. Outside of the in express

docs.mongodb.com

 

연산 결과를 페이징 처리하고자 할때에는 $facet 명령을 이용하여 $skip과 $limit으로 처리하면 된다.

단, 주의할 점은 aggregate 명령 결과는 항상 list()를 이용하여 배열로 바꾼다음 값을 추출해야한다는 점이다.

아래의 예제의 경우 result[0]['data']로 접근을 해야 페이징된 결과값을 얻어올 수 있다.

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

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

 

How to use MongoDB aggregation for pagination?

I want to perform an aggregation query that does basic pagination: Find all orders that belongs to a certain company_id Sort the orders by order_number Count the total number of documents Skips to...

stackoverflow.com

https://docs.mongodb.com/manual/reference/operator/aggregation/facet/

 

$facet (aggregation) — MongoDB Manual

Behavior Facet-related aggregation stages categorize and group incoming documents. Specify any of the following facet-related stages within different $facet sub-pipeline’s to perform a multi-faceted aggregation: Other aggregation stages can also be used wi

docs.mongodb.com