MongoDB의 Aggregation Pipeline은 데이터의 변환 및 집계를 수행할 수 있는 매우 강력한 기능입니다. 여러 단계로 구성된 파이프라인을 통해 데이터베이스 내의 문서를 처리할 수 있습니다. 각 단계는 특정 작업을 수행하며, 단계별로 연산자를 사용하여 원하는 작업을 정의할 수 있습니다.
지정된 조건과 일치하는 문서만 전달하는 연산자, Pipeline의 앞 부분에 배치하여야 처리량을 최적화할 수 있습니다.
{ $match: { status: "A" } }
지정된 필드로 그룹화하고, 집계 함수를 사용하여 각 그룹의 데이터를 집계합니다.
{ $group: { _id: "$status", total: { $sum: "$amount" } } }
문서의 필드를 포함하거나 제외하고, 새로운 필드를 생성할 수 있습니다.
{ $project: { title: 1, author: 1, year: { $year: "$date" } } }
정렬 조건에 따라 문서를 정렬합니다.
{ $sort: { age: -1 } }
지정된 개수만큼의 문서를 반환합니다.
{ $limit: 5 }
지정된 개수만큼의 문서를 건너뜁니다.
{ $skip: 10 }
배열 필드를 분해하여 여러 문서로 확장합니다.
{ $unwind: "$items" }
다른 컬렉션과 조인하여 데이터를 결합합니다.
{
$lookup: {
from: "orders",
localField: "customerId",
foreignField: "customerId",
as: "orders"
}
}
새로운 필드를 추가합니다.
{ $addFields: { totalCost: { $multiply: ["$price", "$quantity"] } } }
문서의 루트 요소를 바꿉니다.
{ $replaceRoot: { newRoot: "$items" } }
파이프라인의 출력을 새로운 컬렉션에 저장합니다.
{ $out: "newCollection" }
문서의 수를 세고, 그 결과를 새로운 필드로 반환합니다.
{ $count: "totalCount" }
여러 개의 하위 파이프라인을 동시에 실행하여, 복잡한 다중 단계 집계 작업을 수행할 수 있습니다.
{
$facet: {
"categorizedByPrice": [
{ $match: { price: { $exists: 1 } } },
{ $bucket: { groupBy: "$price", boundaries: [0, 50, 100, 200, 300] } }
],
"categorizedByYear": [
{ $match: { year: { $exists: 1 } } },
{ $bucketAuto: { groupBy: "$year", buckets: 4 } }
]
}
}
결과를 기존 컬렉션에 병합하거나 새 컬렉션에 저장합니다.
{
$merge: {
into: "mergedCollection",
whenMatched: "merge",
whenNotMatched: "insert"
}
}
위 14개의 연산자 외에도 다른 많은 연산자가 존재하기에 각 상황에 맞는 연산자들 사용한다면 더욱 복잡한 쿼리를 작성할 수 있습니다.
sales 컬렉션
[
{ "date": "2023-07-01", "store": "A", "item": "apple", "quantity": 10, "price": 2 },
{ "date": "2023-07-01", "store": "A", "item": "banana", "quantity": 5, "price": 1 },
{ "date": "2023-07-01", "store": "B", "item": "apple", "quantity": 8, "price": 2 },
{ "date": "2023-07-02", "store": "A", "item": "apple", "quantity": 6, "price": 2 },
{ "date": "2023-07-02", "store": "B", "item": "banana", "quantity": 7, "price": 1 }
]
{ $match: { date: "2023-07-01" } }
{ $group: { _id: "$store", totalQuantity: { $sum: "$quantity" }, totalRevenue: { $sum: { $multiply: ["$quantity", "$price"] } } } }
{ $project: { store: "$_id", totalQuantity: 1, totalRevenue: 1, _id: 0 } }
{ $sort: { totalRevenue: -1 } }
{
$lookup: {
from: "stores",
localField: "store",
foreignField: "storeId",
as: "storeDetails"
}
}
예를 들어, 2023-07-01 날짜의 판매 데이터를 필터링하고, 각 상점별로 총 수익을 계산하여 상위 1개의 결과를 얻는 전체 파이프라인은 다음과 같이 작성합니다.
[
{ $match: { date: "2023-07-01" } },
{ $group: { _id: "$store", totalQuantity: { $sum: "$quantity" }, totalRevenue: { $sum: { $multiply: ["$quantity", "$price"] } } } },
{ $project: { store: "$_id", totalQuantity: 1, totalRevenue: 1, _id: 0 } },
{ $sort: { totalRevenue: -1 } },
{ $limit: 1 }
]