MongoDB에서 배열 내부의 항목들을 특정 기준(예: 가격)으로 그룹화하고, 각 그룹에 속한 요소의 개수를 집계해야 하는 경우가 자주 있습니다. 이때 애그리게이션 파이프라인의 $unwind, $group, $sort 연산자를 조합하면 간단하게 해결할 수 있습니다.
아래 예제를 통해 배열 안에 담긴 여러 제품 정보를 가격별로 그룹화하고, 같은 가격의 제품이 몇 개인지 계산하는 방법을 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 제품 정보 배열(ProductInformation)을 포함하는 문서로 컬렉션을 생성합니다. insertOne() 메서드를 사용합니다.
> db.demo566.insertOne(
... {
... "ProductInformation" : [
... {
... "ProductName" : "Product-1",
... "ProductPrice" : 100
... },
... {
... "ProductName" : "Product-2",
... "ProductPrice" : 1100
... },
... {
... "ProductName" : "Product-3",
... "ProductPrice" : 100
... },
... {
... "ProductName" : "Product-4",
... "ProductPrice" : 1100
... },
... {
... "ProductName" : "Product-5",
... "ProductPrice" : 100
... }
... ]
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e908e2339cfeaaf0b97b57a")
}2. 저장된 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.
> db.demo566.find();
위 쿼리는 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5e908e2339cfeaaf0b97b57a"), "ProductInformation" : [
{ "ProductName" : "Product-1", "ProductPrice" : 100 },
{ "ProductName" : "Product-2", "ProductPrice" : 1100 },
{ "ProductName" : "Product-3", "ProductPrice" : 100 },
{ "ProductName" : "Product-4", "ProductPrice" : 1100 },
{ "ProductName" : "Product-5", "ProductPrice" : 100 }
] }3. 배열 항목을 가격별로 그룹화하는 쿼리
배열 항목을 그룹화하려면 aggregate() 파이프라인에서 다음 세 단계를 순서대로 수행합니다.
- $unwind: ProductInformation 배열의 각 요소를 개별 문서로 분리합니다.
- $group: 분리된 문서들을 ProductPrice 값을 기준으로 묶고, $sum: 1을 사용해 각 그룹의 개수를 셉니다.
- $sort: 결과를 _id(가격) 오름차순으로 정렬합니다.
> db.demo566.aggregate([
... {
... "$unwind": "$ProductInformation"
... },
... {
... "$group": {
... "_id": "$ProductInformation.ProductPrice",
... "Value": { "$sum" : 1 }
... }
... },
... { "$sort": { "_id" : 1 } }
... ])4. 실행 결과
위 애그리게이션 쿼리는 다음과 같은 출력을 생성합니다.
{ "_id" : 100, "Value" : 3 }
{ "_id" : 1100, "Value" : 2 }결과를 해석해 보면, 가격이 100인 제품은 3개(Product-1, Product-3, Product-5), 가격이 1100인 제품은 2개(Product-2, Product-4)임을 한눈에 확인할 수 있습니다.
이처럼 $unwind로 배열을 펼친 뒤 $group으로 집계하고 $sort로 정렬하는 패턴은 MongoDB에서 배열 데이터를 통계적으로 분석할 때 매우 유용하게 활용됩니다.