Aggregation Pipeline

MongoDB에서 데이터를 여러 단계(Stage)를 순차적으로 거쳐 집계·변환·분석하는 처리 방식입니다.

핵심 개념

컬렉션 → [Stage1] → [Stage2] → [Stage3] → 최종 결과
          $match    $group     $sort
         (필터링)   (집계)    (정렬)

각 Stage의 출력이 다음 Stage의 입력이 됨

주요 Stage

StageSQL 대응설명
$matchWHERE조건으로 문서 필터링
$groupGROUP BY특정 기준으로 그룹화
$sortORDER BY정렬
$projectSELECT필드 선택/제외/변환
$limitLIMIT결과 수 제한
$lookupJOIN다른 컬렉션 참조
$unwind-배열을 개별 문서로 펼침

예시 - 유저별 총 주문금액 집계

db.orders.aggregate([
  // 1단계: 완료 주문만 필터
  { $match: { status: "완료" } },

  // 2단계: 유저별 그룹화
  {
    $group: {
      _id: "$user_id",
      totalAmount: { $sum: "$amount" },
      orderCount:  { $sum: 1 }
    }
  },

  // 3단계: 총액 내림차순 정렬
  { $sort: { totalAmount: -1 } }
]);

// 결과
{ "_id": 1, "totalAmount": 30000, "orderCount": 2 }
{ "_id": 2, "totalAmount": 15000, "orderCount": 1 }

SQL과 비교

-- SQL
SELECT user_id, SUM(amount) AS totalAmount, COUNT(*) AS orderCount
FROM orders
WHERE status = '완료'
GROUP BY user_id
ORDER BY totalAmount DESC;
// Aggregation Pipeline - 동일한 동작
db.orders.aggregate([
  { $match: { status: "완료" } },           -- WHERE
  { $group: { _id: "$user_id",              -- GROUP BY
              totalAmount: { $sum: "$amount" },
              orderCount:  { $sum: 1 } } },
  { $sort: { totalAmount: -1 } }            -- ORDER BY
]);

$lookup과의 관계

// $lookup도 Pipeline의 Stage 중 하나
db.orders.aggregate([
  { $match: { status: "완료" } },
  {
    $lookup: {                  // JOIN
      from: "users",
      localField: "user_id",
      foreignField: "_id",
      as: "user_info"
    }
  },
  { $unwind: "$user_info" },   // 배열 → 단일 객체
  { $group: { ... } }
]);

성능 팁

O $match, $limit은 최대한 앞 단계에 배치
   → 처리할 문서 수를 먼저 줄여야 성능 향상

X 나쁜 예
aggregate([ $group → $match ])  // 전체 집계 후 필터링

O 좋은 예
aggregate([ $match → $group ])  // 필터링 후 집계

Aggregation Pipeline은 MongoDB에서 집계, JOIN($lookup), 변환을 모두 처리하는 핵심 프레임워크입니다. $lookup은 이 Pipeline 안에 속한 하나의 Stage입니다.

CSLOG에서 보기