MongoDB 애그리게이션 파이프라인에서 $group 단계의 처리 속도를 높이려면 $project, $unwind 같은 단계를 함께 활용해 불필요한 데이터를 조기에 제거하고 그룹화 대상을 최소화하는 것이 효과적입니다. 아래 예제를 통해 실제 동작 과정을 살펴보겠습니다.
1. 샘플 컬렉션 생성
먼저 배열 필드를 가진 문서 하나를 삽입하여 컬렉션을 생성합니다.
> db.demo423.insertOne({"Information":[101,110,87,110,98,115,101,115,89,115]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e73a60e9822da45b30346e6")
}
2. 컬렉션의 모든 문서 조회
find() 메서드를 사용하면 컬렉션의 모든 문서를 확인할 수 있습니다.
> db.demo423.find();
위 쿼리는 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5e73a60e9822da45b30346e6"), "Information" : [ 101, 110, 87, 110, 98, 115, 101, 115, 89, 115 ] }
3. $group 단계가 포함된 최적화된 애그리게이션 쿼리
다음은 배열 요소별 빈도수를 계산하는 애그리게이션 쿼리입니다. $project로 필요한 필드만 추출하고, $unwind로 배열을 개별 문서로 분해한 뒤 $group으로 빈도를 집계하며, 마지막으로 $sort와 $limit으로 상위 결과만 반환합니다.
> db.demo423.aggregate([
... {
... $project: {_id: 0, 'Information': 1}
... },
... {
... $unwind: '$Information'
... },
... {
... $group:{_id: '$Information', frequency:{$sum: 1}}
... },
... {
... $sort:{frequency:-1}
... },
... {
... $limit:2
... }
... ])
위 애그리게이션은 다음과 같은 결과를 출력합니다.
{ "_id" : 115, "frequency" : 3 }
{ "_id" : 110, "frequency" : 2 }
$group 단계 속도 향상을 위한 핵심 팁
- 조기 필터링:
$match와$project를 파이프라인 앞쪽에 배치하면$group으로 전달되는 문서 수와 필드 수가 줄어들어 전체 처리량이 크게 향상됩니다. - 불필요한 필드 제외: 위 예제처럼
$project에서_id: 0으로 설정해 그룹화에 필요 없는 필드를 제거하면 메모리 사용량을 절감할 수 있습니다. - allowDiskUse 옵션 활용: 대용량 데이터를 그룹화할 때는
allowDiskUse: true옵션을 지정해 100MB 메모리 제한 초과 오류를 방지하세요. - 인덱스 설계: 파이프라인 앞단의
$match,$sort가 인덱스를 활용하도록 하면 스캔 비용이 줄어들어 후속$group단계까지 빠르게 진행됩니다.