MongoDB에서 배열 필드 안에 동일한 이름이 여러 번 등장할 때, 각 이름별로 몇 번 나타나는지 집계(aggregation)를 통해 손쉽게 확인할 수 있습니다. 이 글에서는 $unwind, $group, $project 연산자를 활용해 중복 이름별 필드 값 개수를 구하는 방법을 예제와 함께 단계별로 살펴보겠습니다.
1. 샘플 컬렉션 생성
먼저 예제에 사용할 컬렉션을 생성합니다. details 배열 안에는 여러 사람의 이름(Name)과 과목(Subject) 정보가 저장되어 있습니다.
> db.demo558.insertOne(
... {
... _id : 100,
... CountryCode:101,
... details: [
... {
... Name:"Chris",
... Subject:"MySQL"
... },
... {
... Name:"Chris",
... Subject:"MongoDB"
... },
... {
... Name:"Chris",
... Subject:"Java"
... },
... {
... Name:"Bob",
... Subject:"Python"
... },
... {
... Name:"Bob",
... Subject:"Java"
... }
... ]
... }
... )
{ "acknowledged" : true, "insertedId" : 100 }
2. 컬렉션 문서 조회하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.demo558.find();
위 명령을 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : 100, "CountryCode" : 101, "details" : [
{ "Name" : "Chris", "Subject" : "MySQL" },
{ "Name" : "Chris", "Subject" : "MongoDB" },
{ "Name" : "Chris", "Subject" : "Java" },
{ "Name" : "Bob", "Subject" : "Python" },
{ "Name" : "Bob", "Subject" : "Java" }
] }
3. 집계 쿼리로 이름별 개수 구하기
다음은 각 이름이 등장한 횟수(NameCount)와 해당 이름에 연결된 과목 수(SubjectCount)를 함께 구하는 집계 쿼리입니다.
> db.demo558.aggregate([
... {$unwind: "$details" },
... {$group: { _id: "$details.Name", NameCount:{$sum : 1}, Subject : {$push: "$details.Subject"}}},
... {$project: { NameCount: 1, SubjectCount : {$size: "$Subject"}}}
... ]).pretty()
쿼리 단계별 설명
- $unwind:
details배열의 각 요소를 개별 문서로 분리하여 처리 대상을 만듭니다. - $group:
Name값을 기준으로 문서를 그룹화하고,$sum: 1로 각 이름의 등장 횟수를 계산합니다. 또한$push를 사용해 같은 그룹에 속한 과목들을 하나의 배열로 모읍니다. - $project: 최종적으로 출력할 필드를 지정하며,
$size연산자로Subject배열의 요소 개수(즉, 과목 수)를 계산합니다.
4. 실행 결과
집계 쿼리를 실행하면 다음과 같은 결과를 얻을 수 있습니다.
{ "_id" : "Bob", "NameCount" : 2, "SubjectCount" : 2 }
{ "_id" : "Chris", "NameCount" : 3, "SubjectCount" : 3 }
결과를 보면 Chris는 3번, Bob은 2번 등장했으며, 각각 3개와 2개의 과목 정보를 가지고 있는 것을 확인할 수 있습니다. 이처럼 MongoDB의 집계 파이프라인을 활용하면 배열 내 중복 데이터를 이름별로 그룹화하고 개수를 손쉽게 분석할 수 있습니다.