집계 파이프라인 (Aggregation Pipeline)
집계 파이프라인 (Aggregation Pipeline)
집계 작업이란
집계(Aggregation) 작업은 여러 문서를 처리하고 계산된 결과를 돌려줍니다. MongoDB를 쓰다 보면 "이 컬렉션에 있는 값들을 묶어서 통계를 내야겠다" 하는 순간이 꼭 오는데요, 그때 이 집계 작업이 동작합니다. 구체적으로는 이런 일들을 할 수 있어요.
- 여러 문서에서 값을 그룹화합니다.
- 그룹화된 데이터에서 단일 결과를 계산합니다.
- 시간에 따른 데이터 변화를 분석합니다.
- 데이터의 최신 버전을 조회합니다.
MongoDB의 집계 연산자(aggregation operator)를 쓰면 데이터를 다른 플랫폼으로 옮기지 않고도 클러스터 안에서 바로 분석을 실행할 수 있습니다.
시작하기
집계 작업을 수행하는 방법은 두 가지입니다.
- 집계 파이프라인(Aggregation Pipeline) — 가장 권장되는 방법이에요.
- 단일 목적 집계 메서드(Single Purpose Aggregation Methods) — 집계 파이프라인보다 기능은 적지만, 컬렉션 단위로 간단히 쓰기 좋습니다.
MongoDB Atlas에 배포되어 있다면 UI에서도 집계 파이프라인을 바로 실행할 수 있습니다.
집계 파이프라인
집계 파이프라인은 문서를 처리하는 하나 이상의 단계(stage) 로 구성됩니다. 이 문서들은 컬렉션에서 오기도 하고, view에서 오거나, 특별히 설계된 단계가 만들어낸 결과일 수도 있어요.
각 단계는 입력으로 들어온 문서에 어떤 작업을 수행합니다. 예를 들어 어떤 단계는 문서를 $filter로 거르고, 다른 단계는 $group으로 묶고, 또 다른 단계는 값을 계산하죠. 그러면 그 단계가 출력한 문서들이 파이프라인에서 다음 단계로 전달됩니다.
집계 파이프라인은 문서 그룹에 대한 결과를 돌려줄 수도 있고, "Updates with Aggregation Pipeline"에서 보여주는 단계들을 이용해 문서 자체를 업데이트하는 데에도 쓸 수 있습니다.
참고
db.collection.aggregate()메서드로 실행되는 집계 파이프라인은, 파이프라인에$merge또는$out단계가 포함되어 있지 않다면 컬렉션의 문서를 수정하지 않습니다.
집계 파이프라인 예시
이 페이지의 예시는 sample_mflix 샘플 데이터 세트의 영화 데이터를 사용합니다. 자체 관리형(셀프 매니지드) MongoDB 배포서버에 이 데이터 세트를 불러오는 방법은 "Load the sample dataset"에서 확인할 수 있고요, 샘플 데이터베이스를 건드렸다면 예시를 그대로 실행하기 위해 데이터베이스를 지우고 다시 만들어야 할 수도 있습니다.
다음 파이프라인은 데이터베이스에서 가장 많은 영화를 감독한 상위 3명의 감독을 찾아냅니다.
먼저 $match 단계로 감독이 등재된 영화만 남깁니다. 여기서는 directors 필드가 존재하고, null도 아니고, 빈 배열($size: 0)도 아닌 문서로 조건을 걸어요.
{
$match : {
"directors" : { $exists: true, $ne: null, $not: {$size: 0} }
}
},
이 $match 단계는 감독 정보가 없는 영화를 걸러내, 뒤에서 처리할 문서 수를 줄여줍니다. 다음으로 $unwind를 써서 directors 배열을 분해합니다. 그래야 감독 한 명씩 따로 세어볼 수 있거든요.
{
$unwind : "$directors"
},
이제 $group으로 문서를 감독 이름(_id)별로 묶고, 각 감독의 영화 수(movieCount)를 $sum: 1로 셉니다.
{
$group : {
_id : "$directors",
movieCount : {
$sum: 1
}
}
},
$sort를 쓰면 남은 문서를 영화 수(movieCount) 기준 내림차순으로 정렬합니다.
{
$sort : {
movieCount : -1
}
},
마지막으로 $limit로 상위 3건만 남깁니다.
{
$limit : 3
}
이 다섯 단계를 합친 전체 파이프라인은 이렇게 생겼어요.
db.movies.aggregate(
[
{
$match : {
"directors" : { $exists: true, $ne: null, $not: {$size: 0} }
}
},
{
$unwind : "$directors"
},
{
$group : {
_id : "$directors",
movieCount : {
$sum: 1
}
}
},
{
$sort : {
movieCount : -1
}
},
{
$limit : 3
}
]
)
그리고 이 파이프라인이 돌려주는 결과입니다.
[
{ _id: 'Woody Allen', movieCount: 40 },
{ _id: 'Martin Scorsese', movieCount: 32 },
{ _id: 'Takashi Miike', movieCount: 31 }
]
샘플 입력 문서가 포함된 실행 가능한 예시는 "Complete Aggregation Pipeline Examples"에서 볼 수 있고, 집계 파이프라인의 더 자세한 내용은 "Aggregation Pipeline" 문서에서 다룹니다.
단일 목적 집계 메서드
단일 목적 집계 메서드는 하나의 컬렉션에서 문서를 집계합니다. 이 메서드들은 집계 파이프라인보다 기능이 적지만, 자주 쓰는 단순한 집계는 빠르게 해결해 줍니다.
| 메서드 | 설명 |
|---|---|
db.collection.estimatedDocumentCount() |
컬렉션 또는 view에 있는 문서의 대략적인 개수를 반환합니다. |
db.collection.count() |
컬렉션 또는 view에 있는 문서의 개수를 반환합니다. |
db.collection.distinct() |
지정된 필드에 대해 고유한 값을 가진 문서의 배열을 반환합니다. |