MongoDB에서 배열 필드에 포함된 요소들의 출현 횟수를 세고, 가장 많이 등장한 상위 요소만 추출하고 싶다면 애그리게이션(Aggregation) 프레임워크를 활용하는 것이 가장 효과적입니다. 이 글에서는 실제 예제를 통해 $unwind, $group, $sort, $limit 파이프라인 단계를 순서대로 사용하여 배열 요소의 최다 빈도를 구하는 방법을 살펴보겠습니다.
1. 샘플 컬렉션 생성하기
먼저 학생 정보를 담은 컬렉션을 생성하고 문서를 삽입합니다. 각 문서는 학생 ID와 해당 학생이 수강하는 과목 배열을 가지고 있습니다.
> db.topCountArrayDemo.insertOne(
... {"StudentId":101 , "StudentSubject": ["C", "MongoDB"]}
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5cc6b3209cb58ca2b005e669")
}
> db.topCountArrayDemo.insertOne(
... {"StudentId":102 , "StudentSubject": ["C", "Java"]}
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5cc6b3219cb58ca2b005e66a")
}
> db.topCountArrayDemo.insertOne(
... {"StudentId":103 , "StudentSubject": ["C", "MongoDB"]}
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5cc6b3229cb58ca2b005e66b")
}2. 저장된 문서 확인하기
find() 메서드를 사용해 컬렉션의 모든 문서를 조회합니다.
> db.topCountArrayDemo.find().pretty();
위 쿼리는 다음과 같은 결과를 출력합니다.
{
"_id" : ObjectId("5cc6b3209cb58ca2b005e669"),
"StudentId" : 101,
"StudentSubject" : [
"C",
"MongoDB"
]
}
{
"_id" : ObjectId("5cc6b3219cb58ca2b005e66a"),
"StudentId" : 102,
"StudentSubject" : [
"C",
"Java"
]
}
{
"_id" : ObjectId("5cc6b3229cb58ca2b005e66b"),
"StudentId" : 103,
"StudentSubject" : [
"C",
"MongoDB"
]
}3. 애그리게이션으로 최다 빈도 요소 집계하기
이제 배열 요소별 출현 횟수를 계산하고, 빈도가 높은 순으로 정렬한 뒤 상위 2개만 가져오는 쿼리를 작성합니다.
> db.topCountArrayDemo.aggregate(
... [
... {
... $unwind: "$StudentSubject"
... },
... {
... $group: {
... _id: "$StudentSubject",
... Frequency: {$sum: 1}
... }
... },
... {
... $sort: {Frequency:-1}
... },
... {
... $limit: 2
... }
... ]
... ).pretty();실행 결과는 다음과 같습니다.
{ "_id" : "C", "Frequency" : 3 }
{ "_id" : "MongoDB", "Frequency" : 2 }파이프라인 단계별 동작 원리
각 단계가 어떤 역할을 하는지 간단히 정리하면 다음과 같습니다.
- $unwind:
StudentSubject배열을 개별 요소 단위로 분해합니다. 하나의 문서가 배열 요소 수만큼 여러 문서로 펼쳐지게 됩니다. - $group: 분해된 요소를 기준으로 그룹화하고,
$sum: 1을 통해 각 요소가 등장한 횟수를Frequency필드에 누적합니다. - $sort:
Frequency값을 내림차순(-1)으로 정렬하여 가장 많이 등장한 요소가 맨 위에 오도록 합니다. - $limit: 정렬된 결과 중 상위 2개의 문서만 반환합니다. 이 값을 조정하면 원하는 만큼의 Top N 요소를 얻을 수 있습니다.
결과를 보면 과목 "C"가 3번, "MongoDB"가 2번 등장했음을 알 수 있습니다. 이처럼 애그리게이션 파이프라인을 조합하면 복잡한 로직 없이도 배열 데이터의 통계를 손쉽게 도출할 수 있습니다.