여러 MongoDB 문서에 걸쳐 반복되는 값의 개수를 구하려면 aggregate() 메서드를 사용하면 됩니다. 이 글에서는 실제 예제를 통해 학생 데이터에서 이름별 중복 횟수를 집계하는 방법을 단계별로 살펴보겠습니다.
1. 컬렉션 생성 및 문서 삽입
먼저 insertOne() 메서드를 사용해 demo452 컬렉션을 생성하고 문서들을 삽입합니다.
> db.demo452.insertOne({"StudentName":"John","StudentAge":21});{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b7e3371f552a0ebb0a6f3")
}
> db.demo452.insertOne({"StudentName":"John","StudentAge":22});{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b7e3671f552a0ebb0a6f4")
}
> db.demo452.insertOne({"StudentName":"John","StudentAge":23});{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b7e3971f552a0ebb0a6f5")
}
> db.demo452.insertOne({"StudentName":"David","StudentAge":24});{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b7e4371f552a0ebb0a6f6")
}
> db.demo452.insertOne({"StudentName":"David","StudentAge":25});{
"acknowledged" : true,
"insertedId" : ObjectId("5e7b7e4571f552a0ebb0a6f7")
}위 코드에서 'John'은 3번, 'David'는 2번 등장하므로, 최종적으로 각 이름이 몇 번 반복되었는지 확인할 수 있어야 합니다.
2. find()로 전체 문서 조회하기
삽입된 모든 문서를 확인하려면 find() 메서드를 사용합니다.
> db.demo452.find();
실행하면 다음과 같은 출력 결과가 나타납니다.
{ "_id" : ObjectId("5e7b7e3371f552a0ebb0a6f3"), "StudentName" : "John", "StudentAge" : 21 }
{ "_id" : ObjectId("5e7b7e3671f552a0ebb0a6f4"), "StudentName" : "John", "StudentAge" : 22 }
{ "_id" : ObjectId("5e7b7e3971f552a0ebb0a6f5"), "StudentName" : "John", "StudentAge" : 23 }
{ "_id" : ObjectId("5e7b7e4371f552a0ebb0a6f6"), "StudentName" : "David", "StudentAge" : 24}
{ "_id" : ObjectId("5e7b7e4571f552a0ebb0a6f7"), "StudentName" : "David", "StudentAge" : 25}3. aggregate()로 반복 값 개수 집계하기
다음은 MongoDB 문서들에서 반복되는 값의 개수를 구하는 집계 쿼리입니다.
> db.demo452.aggregate([
... {$group: {_id:"$StudentName", count:{$sum:1}}},
... {$sort: {count:-1}},
...
... {$group: {_id:1, StudentName:{$push:{StudentName:"$_id", count:"$count"}}}},
... {$project: {
... first : {$arrayElemAt: ["$StudentName", 0]},
... second: {$arrayElemAt: ["$StudentName", 1]},
... others: {$slice:["$StudentName", 2, {$size: "$StudentName"}]}
... }
... },
...
... {$project: {
... status: [
... "$first",
... "$second",
... {
... StudentName: "New Student Name",
... count: {$sum: "$others.count"}
... }
... ]
... }
... },
...
... {$unwind: "$status"},
... {$project: { _id:0, StudentName: "$status.StudentName", count: "$status.count" }}
... ])쿼리 동작 방식
- $group + $sum:1: StudentName 기준으로 문서를 그룹화하여 각 이름이 등장한 횟수를 계산합니다.
- $sort: 개수(count)를 내림차순으로 정렬해 가장 많이 반복된 값을 앞에 배치합니다.
- $arrayElemAt / $slice: 정렬된 결과에서 상위 두 항목(first, second)과 나머지 항목(others)을 분리합니다.
- $unwind: 배열 형태의 status 필드를 개별 문서로 펼쳐서 출력합니다.
4. 실행 결과
위 집계 쿼리를 실행하면 다음과 같은 출력 결과를 얻을 수 있습니다.
{ "StudentName" : "John", "count" : 3 }
{ "StudentName" : "David", "count" : 2 }
{ "StudentName" : "New Student Name", "count" : 0 }결과를 보면 'John'이 3번, 'David'가 2번 반복되었으며, 상위 두 항목 외의 나머지 값들은 'New Student Name'이라는 항목으로 묶여 그 합계(0)가 함께 출력됩니다. 이처럼 aggregate() 파이프라인을 활용하면 여러 문서에 흩어진 반복 값을 손쉽게 그룹화하고 개수를 집계할 수 있습니다.