Data/MongoDB

[MongoDB]Aggregation Framework: 효율적인 데이터 처리와 분석

누구세연 2024. 12. 27. 22:17

MongoDB Aggregation은 데이터를 효율적으로 처리하고 분석할 때 매우 강력한 도구입니다.

이 글에서는 Aggregation에 대해 정리해 보겠습니다. 👩🏻‍💻

 

Aggregation이란?

Aggregation은 데이터를 가공하거나 요약하여 원하는 결과를 얻는 작업을 말합니다.

SQL에서는 GROUP BY, HAVING, SUM() 같은 명령어로 비슷한 작업을 할 수 있지만, MongoDB는 Aggregation Framework를 통해 훨씬 유연하고 강력한 방식으로 데이터를 처리할 수 있습니다.

 

 

Aggregation의 주요 방식

  1. Aggregation Framework: 단계별로 데이터를 처리하는 파이프라인 방식.
  2. Map-Reduce: 대량의 데이터를 병렬로 처리하는 방식.
  3. Single Purpose Aggregation Methods: 특정 작업을 위한 간단한 함수들(count(), avg() 등).

이 글에서는 주로 Aggregation Framework에 대해 다룹니다.

 

 

Aggregation Pipeline 구조

Aggregation Pipeline은 여러 단계로 구성되어 있으며, 각 단계는 입력 데이터를 변환하여 다음 단계로 전달합니다. 이 과정을 통해 데이터를 점진적으로 가공할 수 있습니다.

Pipeline의 주요 단계

  • $match: 데이터를 필터링 (SQL의 WHERE와 유사)
  • $group: 데이터를 그룹화하고 요약 (SQL의 GROUP BY와 유사)
  • $project: 출력할 필드와 형식을 지정
  • $sort: 데이터를 정렬
  • $limit: 반환할 문서 수 제한
  • $skip: 문서를 건너뛰기
  • $lookup: 다른 컬렉션과 조인
  • $unwind: 배열을 개별 문서로 펼치기

 

간단한 Pipeline 예제

db.orders.aggregate([ 
	{ $match: { status: "completed" } }, 
	{ $group: { _id: "$customerId", totalAmount: { $sum: "$amount" } } }, 
	{ $sort: { totalAmount: -1 } } 
]);

위 예제는 주문 상태가 completed인 데이터를 필터링하고, 고객별 총 주문 금액을 집계한 후 내림차순으로 정렬하는 작업을 합니다.

 

 

주요 Aggregation 단계 설명과 예제

$match: 데이터 필터링

$match는 특정 조건에 맞는 데이터를 필터링합니다. SQL의 WHERE와 비슷합니다.

db.orders.aggregate([ { $match: { status: "pending", amount: { $gte: 100 } } } ]);

위 예제는 status가 pending이고 amount가 100 이상인 주문만 선택합니다.

 

$group: 데이터 그룹화

$group은 데이터를 그룹화하고, 요약 통계를 계산할 때 사용합니다. SQL의 GROUP BY와 비슷합니다.

db.sales.aggregate([ 
	{ $group: { _id: "$region", totalSales: { $sum: "$amount" } } } 
]);

위 예제는 지역별 총판매 금액을 계산합니다.

 

$lookup: 컬렉션 조인

$lookup은 SQL의 JOIN과 유사한 기능을 제공합니다.

db.orders.aggregate([ 
	{ $lookup: { from: "customers", localField: "customerId", foreignField: "_id", as: "customerDetails" } }
]);

위 예제는 orders 컬렉션과 customers 컬렉션을 customerId와 _id를 기준으로 조인하여 고객 정보를 포함합니다.

 

$unwind: 배열 펼치기

$unwind는 배열 필드를 개별 문서로 펼칩니다.

db.products.aggregate([ 
	{ $unwind: "$categories" }, 
    { $group: { _id: "$categories", productCount: { $sum: 1 } } } 
]);

위 예제는 categories 배열의 각 값을 개별 문서로 변환한 뒤, 카테고리별 제품 수를 집계합니다.

 

$project: 필드 선택과 변환

$project는 필요한 필드만 선택하거나 계산된 필드를 추가할 수 있습니다.

db.orders.aggregate([ 
	{ $project: { orderId: 1, totalAmount: 1, withTax: { $multiply: ["$amount", 1.1] } } } 
]);

위 예제는 orderId, totalAmount 필드를 출력하고, amount에 10% 세금을 더한 값을 withTax로 계산합니다.

 

Aggregation 최적화 팁

  1. Index 활용: $match와 $sort에서 인덱스를 사용하면 성능이 크게 향상됩니다.
  2. Pipeline 단계 배치: 필터링($match)과 정렬($sort)은 파이프라인의 초기에 배치하여 불필요한 데이터 처리를 줄입니다.
  3. 메모리 제한 고려: $group과 $unwind는 메모리를 많이 사용하므로 필요시 `allowDiskUse: true`옵션을 추가하여 디스크 공간을 활용할 수 있습니다.

 

Aggregation의 한계와 주의사항

  1. `$lookup`을 사용할 때 조인 대상 데이터가 많으면 성능 저하가 발생할 수 있습니다. 대규모 데이터셋에서는 주의가 필요합니다.
  2. MongoDB는 기본적으로 메모리 사용량이 100MB로 제한되어 있습니다. 이 한계를 초과하면 오류가 발생할 수 있으므로, 큰 데이터를 처리할 때는 `allowDiskUse: true`를 설정하는 것이 좋습니다.
  3. 복잡한 연산이 필요한 경우 Map-Reduce 방식이 더 적합할 수 있습니

 

💡 MongoDB Aggregation Framework는 데이터를 효율적으로 처리하고 분석하는 데 매우 강력한 도구입니다.
Aggregation Pipeline은 성능과 유연성 모두를 제공하므로, 적절히 사용하면 복잡한 데이터 처리 작업도 손쉽게 수행할 수 있습니다.

 

참고: https://www.mongodb.com/developer/products/mongodb/introduction-aggregation-framework/