문서들을 특정 기준으로 묶어 처리하려면 MongoDB의 aggregate() 메서드에서 $group 연산자를 사용하면 됩니다. 이 글에서는 서로 다른 문서에 흩어져 있는 동일한 id 값을 가진 요소들을 하나로 그룹화하는 방법을 단계별로 살펴보겠습니다.
1. 컬렉션 생성 및 문서 삽입
먼저 예제로 사용할 컬렉션을 만들고 문서를 삽입합니다.
> db.demo602.insertOne({id:1,Name:"Chris"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e960080ed011c280a0905c9") }
> db.demo602.insertOne({id:2,Name:"David"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e960086ed011c280a0905ca") }
> db.demo602.insertOne({id:1,Name:"Bob"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e96008ced011c280a0905cb") }
> db.demo602.insertOne({id:3,Name:"Mike"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e960092ed011c280a0905cc") }
> db.demo602.insertOne({id:2,Name:"John"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e960099ed011c280a0905cd") }
> db.demo602.insertOne({id:1,Name:"Sam"});
{ "acknowledged" : true, "insertedId" : ObjectId("5e9600a1ed011c280a0905ce") }위 예제에서는 id 값이 1인 문서 3개, 2인 문서 2개, 3인 문서 1개가 저장되어 있습니다.
2. find()로 전체 문서 확인하기
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.demo602.find();
실행 결과는 다음과 같습니다.
{ "_id" : ObjectId("5e960080ed011c280a0905c9"), "id" : 1, "Name" : "Chris" }
{ "_id" : ObjectId("5e960086ed011c280a0905ca"), "id" : 2, "Name" : "David" }
{ "_id" : ObjectId("5e96008ced011c280a0905cb"), "id" : 1, "Name" : "Bob" }
{ "_id" : ObjectId("5e960092ed011c280a0905cc"), "id" : 3, "Name" : "Mike" }
{ "_id" : ObjectId("5e960099ed011c280a0905cd"), "id" : 2, "Name" : "John" }
{ "_id" : ObjectId("5e9600a1ed011c280a0905ce"), "id" : 1, "Name" : "Sam" }3. $group으로 유사한 ID 그룹화하기
다음은 서로 다른 문서에 있는 동일한 id를 가진 요소들을 집계하는 쿼리입니다. 두 단계의 $group 파이프라인을 사용합니다.
- 첫 번째 $group: id와 Name 조합을 기준으로 그룹화하고, 각 조합의 등장 횟수를
$sum으로 계산합니다. - 두 번째 $group: id만을 기준으로 다시 그룹화하고,
$push를 통해 해당 id에 속한 이름과 빈도 목록을 배열로 만듭니다.
> db.demo602.aggregate([
... { $group: {
... '_id': {id:"$id", "Name" : "$Name"},
... "count" : { "$sum": 1 }
... }},
... { $group: {
... '_id': "$_id.id",
... "ListOfName" : {"$push" : {Name:"$_id.Name", Frequency: "$count"}}
... }},
... ],
... {'allowDiskUse': true}
... );실행 결과는 다음과 같습니다.
{ "_id" : 2, "ListOfName" : [
{ "Name" : "John", "Frequency" : 1 },
{ "Name" : "David", "Frequency" : 1 }
] }
{ "_id" : 3, "ListOfName" : [
{ "Name" : "Mike", "Frequency" : 1 }
] }
{ "_id" : 1, "ListOfName" : [
{ "Name" : "Sam", "Frequency" : 1 },
{ "Name" : "Bob", "Frequency" : 1 },
{ "Name" : "Chris", "Frequency" : 1 }
] }결과 해석
출력 결과를 보면 id가 같은 문서들이 하나의 그룹으로 묶였습니다. 예를 들어 id가 1인 문서 세 개는 Sam, Bob, Chris라는 이름과 각각의 빈도(Frequency)를 담은 배열로 정리되었습니다. 이처럼 $group과 $push를 조합하면 여러 문서에 분산된 데이터를 손쉽게 통합할 수 있으며, allowDiskUse 옵션을 활성화하면 대용량 데이터 처리 시 디스크를 임시로 사용해 메모리 제한 문제도 피할 수 있습니다.