MongoDB에서 특정 필드를 기준으로 문서를 그룹화하여 선택하려면 집계(aggregation) 파이프라인의 $group 연산자와 $project 연산자를 함께 사용하면 됩니다. 이 글에서는 예제 컬렉션을 만들고, 실제 쿼리 작성부터 결과 확인까지 단계별로 살펴보겠습니다.
1단계: 샘플 컬렉션 생성
먼저 insertOne() 메서드로 컬렉션을 생성하고 문서를 삽입합니다.
> db.demo540.insertOne({id:1,"Name":"Chris","CountryName":"US"});{
"acknowledged" : true, "insertedId" : ObjectId("5e8ca368ef4dcbee04fbbc0e")
}
> db.demo540.insertOne({id:1,"Name":"Chris","CountryName":"UK"});{
"acknowledged" : true, "insertedId" : ObjectId("5e8ca36bef4dcbee04fbbc0f")
}
> db.demo540.insertOne({id:1,"Name":"Chris","CountryName":"AUS"});{
"acknowledged" : true, "insertedId" : ObjectId("5e8ca370ef4dcbee04fbbc10")
}위 예제에서는 동일한 id(1)와 Name(Chris)을 가진 세 개의 문서를 삽입했으며, CountryName 값만 서로 다릅니다(US, UK, AUS).
2단계: 저장된 문서 전체 조회
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 확인할 수 있습니다.
> db.demo540.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e8ca368ef4dcbee04fbbc0e"), "id" : 1, "Name" : "Chris", "CountryName" : "US" }
{ "_id" : ObjectId("5e8ca36bef4dcbee04fbbc0f"), "id" : 1, "Name" : "Chris", "CountryName" : "UK" }
{ "_id" : ObjectId("5e8ca370ef4dcbee04fbbc10"), "id" : 1, "Name" : "Chris", "CountryName" : "AUS" }3단계: $group과 $project로 그룹화 쿼리 작성
다음은 id와 Name 필드를 기준으로 문서를 그룹화하는 집계 쿼리입니다.
> var query = [
... {
... "$group": {
... "_id": {
... "id": "$id",
... "Name": "$Name"
... },
... "details": {
... "$push": {
... "CountryName": "$CountryName"
... }
... }
... }
... },
... {
... "$project": {
... "_id": "$_id.id",
... "Name": "$_id.Name",
... "details": 1
... }
... }
... ];
> db.demo540.aggregate(query).pretty();
쿼리 동작 원리
- $group:
_id에id와Name필드의 조합을 지정하여, 두 필드 값이 같은 문서들을 하나의 그룹으로 묶습니다. - $push: 같은 그룹에 속한 문서들의
CountryName값을details배열로 수집합니다. - $project: 최종 출력 형태를 재구성합니다. 그룹 키였던
_id.id와_id.Name을 각각_id와Name필드로 꺼내어 결과를 보기 좋게 정리합니다.
쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{
"_id" : 1,
"Name" : "Chris",
"details" : [
{
"CountryName" : "US"
},
{
"CountryName" : "UK"
},
{
"CountryName" : "AUS"
}
]
}이처럼 $group과 $push, $project를 조합하면 여러 문서를 특정 필드 기준으로 하나의 문서로 묶고, 관련 데이터를 하위 배열 형태로 깔끔하게 정리할 수 있습니다. 대량의 데이터를 요약하거나 관계형 데이터베이스의 GROUP BY와 유사한 처리가 필요할 때 매우 유용하게 활용할 수 있습니다.