MongoDB Aggregation은 데이터를 효율적으로 처리하고 분석할 때 매우 강력한 도구입니다.
이 글에서는 Aggregation에 대해 정리해 보겠습니다. 👩🏻💻
Aggregation이란?
Aggregation은 데이터를 가공하거나 요약하여 원하는 결과를 얻는 작업을 말합니다.
SQL에서는 GROUP BY, HAVING, SUM() 같은 명령어로 비슷한 작업을 할 수 있지만, MongoDB는 Aggregation Framework를 통해 훨씬 유연하고 강력한 방식으로 데이터를 처리할 수 있습니다.
Aggregation의 주요 방식
- Aggregation Framework: 단계별로 데이터를 처리하는 파이프라인 방식.
- Map-Reduce: 대량의 데이터를 병렬로 처리하는 방식.
- 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 최적화 팁
- Index 활용: $match와 $sort에서 인덱스를 사용하면 성능이 크게 향상됩니다.
- Pipeline 단계 배치: 필터링($match)과 정렬($sort)은 파이프라인의 초기에 배치하여 불필요한 데이터 처리를 줄입니다.
- 메모리 제한 고려: $group과 $unwind는 메모리를 많이 사용하므로 필요시 `allowDiskUse: true`옵션을 추가하여 디스크 공간을 활용할 수 있습니다.
Aggregation의 한계와 주의사항
- `$lookup`을 사용할 때 조인 대상 데이터가 많으면 성능 저하가 발생할 수 있습니다. 대규모 데이터셋에서는 주의가 필요합니다.
- MongoDB는 기본적으로 메모리 사용량이 100MB로 제한되어 있습니다. 이 한계를 초과하면 오류가 발생할 수 있으므로, 큰 데이터를 처리할 때는 `allowDiskUse: true`를 설정하는 것이 좋습니다.
- 복잡한 연산이 필요한 경우 Map-Reduce 방식이 더 적합할 수 있습니
💡 MongoDB Aggregation Framework는 데이터를 효율적으로 처리하고 분석하는 데 매우 강력한 도구입니다.
Aggregation Pipeline은 성능과 유연성 모두를 제공하므로, 적절히 사용하면 복잡한 데이터 처리 작업도 손쉽게 수행할 수 있습니다.
참고: https://www.mongodb.com/developer/products/mongodb/introduction-aggregation-framework/
'Data > MongoDB' 카테고리의 다른 글
| [MongoDB] Single Purpose Aggregation: 간단한 집계 작업 (0) | 2024.12.31 |
|---|---|
| [MongoDB] Map-Reduce: 대량 데이터 처리의 유연한 방법 (0) | 2024.12.29 |
| MongoDB 인덱스와 인덱싱 전략 이해하기 (3) | 2024.10.31 |
| [MongoDB] Spring Boot에서 임베디드 MongoDB를 사용하는 방법 (0) | 2024.06.30 |
| [MongoDB] _class 필드 개념과 제거 방법 (0) | 2024.06.29 |