Computer >> 컴퓨터 >  >> 프로그래밍 >> MongoDB

MongoDB에서 중복된 필드 값을 기준으로 점수 합산하는 방법 ($group 활용)

여러 문서에 흩어져 있는 수치를 하나로 합산해야 할 때가 있습니다. 예를 들어 동일한 사용자의 여러 시험 점수를 한 번에 집계하는 경우입니다. 이럴 때 MongoDB 애그리게이션 파이프라인의 $group 연산자를 활용하면 손쉽게 해결할 수 있습니다. 이 글에서는 실제 예제를 통해 단계별로 살펴보겠습니다.

1. 샘플 컬렉션 생성 및 문서 삽입

먼저 실습에 사용할 컬렉션을 만들고 문서를 삽입합니다. 아래 예제에서는 이름(Name), 두 개의 점수(Score1, Score2), 국가(CountryName) 필드를 가진 문서를 사용합니다.

> db.demo512.insertOne({"Name":"Chris","Score1":45,"Score2":65,"CountryName":"US"});{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e884d96987b6e0e9d18f588")
}
> db.demo512.insertOne({"Name":"Chris","Score1":41,"Score2":45,"CountryName":"US"});{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e884da2987b6e0e9d18f589")
}
> db.demo512.insertOne({"Name":"Bob","Score1":75,"Score2":55,"CountryName":"US"});{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e884db2987b6e0e9d18f58a")
}
> db.demo512.insertOne({"Name":"Bob","Score1":65,"Score2":90,"CountryName":"US"});{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e884dc2987b6e0e9d18f58b")
}

2. find()로 전체 문서 조회하기

문서를 모두 삽입했다면, find() 메서드를 사용해 컬렉션의 전체 문서를 확인할 수 있습니다.

> db.demo512.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e884d96987b6e0e9d18f588"), "Name" : "Chris", "Score1" : 45, "Score2" :
65, "CountryName" : "US" }
{ "_id" : ObjectId("5e884da2987b6e0e9d18f589"), "Name" : "Chris", "Score1" : 41, "Score2" :
45, "CountryName" : "US" }
{ "_id" : ObjectId("5e884db2987b6e0e9d18f58a"), "Name" : "Bob", "Score1" : 75, "Score2" :
55, "CountryName" : "US" }
{ "_id" : ObjectId("5e884dc2987b6e0e9d18f58b"), "Name" : "Bob", "Score1" : 65, "Score2" :
90, "CountryName" : "US" }

출력 결과를 보면 Chris와 Bob의 문서가 각각 2개씩 존재합니다. 이제 이름을 기준으로 그룹화하여 Score1과 Score2를 각각 합산해 보겠습니다.

3. $group으로 중복 값 기준 점수 합산하기

다음은 Name 필드를 기준으로 그룹화하고, $sum 연산자로 Score1과 Score2의 합계를 구한 뒤, 최종 결과를 새 컬렉션 demo513에 저장하는 집계 쿼리입니다.

> db.demo512.aggregate([
...    {
...        "$group": {
...            "_id": "$Name",
...            "Score1": { "$sum": "$Score1" },
...            "Score2": { "$sum": "$Score2" },
...            "CountryName": { "$first": "$CountryName" }
...        }
...    },
...    {
...        "$project": {
...            "_id": 0,
...            "Name": "$_id",
...            "Score1": 1,
...            "Score2": 1,
...            "CountryName": 1
...        }
...    },
...    { "$out": "demo513" }
... ])

각 파이프라인 단계의 역할은 다음과 같습니다.

  • $group: _id를 $Name으로 지정하여 이름이 같은 문서들을 하나의 그룹으로 묶습니다.
  • $sum: 각 그룹 내 Score1, Score2 값을 모두 더해 합계를 계산합니다.
  • $first: 그룹 내 첫 번째 문서의 CountryName 값을 가져옵니다.
  • $project: 불필요한 _id 필드는 제외하고, 그룹 키($_id)를 Name이라는 새 필드로 변환해 출력합니다.
  • $out: 집계 결과를 demo513이라는 새 컬렉션에 저장하여 재사용할 수 있게 합니다.

4. 합산 결과 확인하기

결과가 저장된 demo513 컬렉션을 조회해 봅니다.

> db.demo513.find();

실행 결과는 다음과 같습니다.

{ "_id" : ObjectId("5e884f0e79442efd15c6eae0"), "Score1" : 140, "Score2" : 145, "CountryName" : "US", "Name" : "Bob" }
{ "_id" : ObjectId("5e884f0e79442efd15c6eae1"), "Score1" : 86, "Score2" : 110, "CountryName" : "US", "Name" : "Chris" }

Chris의 Score1은 45 + 41 = 86, Score2는 65 + 45 = 110으로 합산되었고, Bob의 Score1은 75 + 65 = 140, Score2는 55 + 90 = 145로 정상적으로 집계된 것을 확인할 수 있습니다.

마무리

이처럼 MongoDB에서는 $group$sum을 조합하면 특정 필드 값이 중복되는 문서들의 수치를 간단하게 합산할 수 있습니다. 여기에 $project로 출력 형태를 다듬고, $out으로 결과를 별도 컬렉션에 저장하면 이후 조회나 분석 작업에서도 편리하게 활용할 수 있습니다.