MongoDB 집계를 활용한 특정 문서 합계 계산
MongoDB에서 값들의 합계를 구하려면 $sum 연산자를 사용하고, 특정 문서들에 대한 합계를 구하려면 $group 스테이지를 함께 활용해야 합니다. 이 글에서는 실제 예제를 통해 특정 사용자의 데이터 합계를 계산하는 과정을 단계별로 살펴보겠습니다.
1단계: 컬렉션 생성 및 문서 삽입
먼저 예제로 사용할 컬렉션을 만들고 문서를 삽입합니다. insertOne() 메서드를 사용하면 됩니다.
> db.calculateSumOfDocument.insertOne({"ListOfUsers":["Carol","Bob"],"UsersDetails":[{"FirstUser":"Carol","TotalLikes":20},{"FirstUser":"Bob","TotalLikes":45}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e084e9125ddae1f53b6220c")
}
> db.calculateSumOfDocument.insertOne({"ListOfUsers":["Carol","Bob"],"UsersDetails":[{"FirstUser":"Carol","TotalLikes":60},{"FirstUser":"Bob","TotalLikes":50}]});
{
"acknowledged" : true,
"insertedId" : ObjectId("5e084f6125ddae1f53b6220d")
}위 명령은 각각 두 명의 사용자(Carol, Bob)와 그들이 받은 좋아요(TotalLikes) 수를 담은 문서 두 개를 컬렉션에 저장합니다.
2단계: find()로 전체 문서 확인
삽입된 모든 문서를 find() 메서드로 조회해 보겠습니다.
> db.calculateSumOfDocument.find().pretty();
위 쿼리를 실행하면 다음과 같은 출력 결과를 얻을 수 있습니다.
{
"_id" : ObjectId("5e084e9125ddae1f53b6220c"),
"ListOfUsers" : [
"Carol",
"Bob"
],
"UsersDetails" : [
{
"FirstUser" : "Carol",
"TotalLikes" : 20
},
{
"FirstUser" : "Bob",
"TotalLikes" : 45
}
]
}
{
"_id" : ObjectId("5e084f6125ddae1f53b6220d"),
"ListOfUsers" : [
"Carol",
"Bob"
],
"UsersDetails" : [
{
"FirstUser" : "Carol",
"TotalLikes" : 60
},
{
"FirstUser" : "Bob",
"TotalLikes" : 50
}
]
}3단계: 집계 파이프라인으로 합계 계산
이제 집계(aggregation)를 사용하여 특정 사용자(여기서는 Carol)의 TotalLikes 합계를 계산해 보겠습니다. 핵심은 배열 필드인 UsersDetails를 $unwind로 분해한 후 조건에 맞는 요소만 걸러내고, $group과 $sum으로 합산하는 것입니다.
> db.calculateSumOfDocument.aggregate([
... {
... "$match": { "UsersDetails.FirstUser": "Carol" }
... },
... { "$unwind" : "$UsersDetails" },
... {
... "$match": { "UsersDetails.FirstUser": "Carol" }
... },
... {
... "$group": {
... "_id": null,
... "total": { "$sum": "$UsersDetails.TotalLikes" }
... }
... }
... ]);실행 결과는 다음과 같습니다.
{ "_id" : null, "total" : 80 }쿼리 동작 원리 설명
- 첫 번째 $match: UsersDetails 배열 안에 Carol이 포함된 문서만 우선 필터링하여 처리 대상을 줄입니다.
- $unwind: 배열 필드인 UsersDetails를 개별 문서 단위로 분해합니다. 이렇게 하면 각 사용자 정보가 독립적인 문서가 됩니다.
- 두 번째 $match: 분해된 문서 중 FirstUser가 Carol인 것만 남깁니다. $match를 두 번 적용하면 불필요한 데이터를 초기에 제거할 수 있어 성능 면에서도 유리합니다.
- $group + $sum: _id를 null로 지정해 전체를 하나의 그룹으로 묶고, TotalLikes 값을 모두 더해 total 필드에 저장합니다.
결과적으로 Carol의 좋아요 수(20 + 60)가 합산되어 total: 80이라는 최종 결과가 반환됩니다. 동일한 방식으로 조건의 이름만 바꾸면 Bob의 합계(45 + 50 = 95)도 손쉽게 구할 수 있습니다.