MongoDB에서 고유 속성 합산 후 결과 가격 구하기
서로 다른 컬렉션 요소에 있는 고유한 속성의 합계를 계산하려면 $cond 연산자와 $group 단계를 함께 사용하면 됩니다. 이 조합을 활용하면 중복되지 않는 속성을 기준으로 가격을 합산한 최종 결과를 얻을 수 있습니다.
1. 샘플 컬렉션 생성
먼저 문서가 담긴 컬렉션을 생성해 보겠습니다.
> db.demo580.insertOne(
... {
... "Name":"John",
... "Id1":"110",
... "Id2":"111",
... "Price":10.5
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e918cebfd2d90c177b5bcae")
}
>
> db.demo580.insertOne(
... {
... "Name":"John",
... "Id1":"111",
... "Id2":"",
... "Price":9.5
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e918cecfd2d90c177b5bcaf")
}2. 저장된 문서 확인
find() 메서드를 사용하면 컬렉션의 모든 문서를 조회할 수 있습니다.
> db.demo580.find();
위 명령은 다음과 같은 결과를 출력합니다.
{ "_id" : ObjectId("5e918cebfd2d90c177b5bcae"), "Name" : "John", "Id1" : "110", "Id2" : "111", "Price" : 10.5 }
{ "_id" : ObjectId("5e918cecfd2d90c177b5bcaf"), "Name" : "John", "Id1" : "111", "Id2" : "", "Price" : 9.5 }3. 고유 속성 합산 쿼리 실행
다음은 서로 다른 컬렉션 요소의 고유한 속성을 합산하는 집계 쿼리입니다.
> db.demo580.aggregate([
... {
... $project: {
... Id1: 1,
... Id2: 1,
... Price: 1,
... match: {
... $cond: [
... {$eq: ["$Id2", ""]},
... "$Id1",
... "$Id2"
... ]
... }
... }
... },
... {
... $group: {
... _id: '$match',
... Price: {$sum: '$Price'},
... resultId: {
... $addToSet: {
... $cond: [
... {$eq: ['$match', '$Id1']},
... null,
... '$Id1'
... ]
... }
... }
... }
... },
... {$unwind: '$resultId'},
... {$match: {
... resultId: {
... $ne: null
... }
... }
... },
... {
... $project: {
... Id1: '$resultId',
... Price: 1,
... _id: 0
... }
... }
... ])이 쿼리는 다음과 같은 결과를 출력합니다.
{ "Price" : 20, "Id1" : "110" }쿼리 동작 방식 살펴보기
이 집계 파이프라인은 다음과 같은 순서로 동작합니다.
- $project + $cond: Id2 필드가 빈 문자열인지 판단하여, 비어 있으면 Id1을, 값이 있으면 Id2를 매칭 키(match)로 지정합니다.
- $group + $sum: 매칭 키를 기준으로 문서를 그룹화하고, 각 그룹에 속한 문서들의 가격(Price)을 합산합니다.
- $addToSet: 그룹 내에서 중복되지 않는 Id1 값만 수집해 고유성을 보장합니다.
- $unwind + $match: 배열 형태의 resultId를 개별 문서로 펼친 뒤 null 값을 제거합니다.
- 최종 $project: 필요한 필드만 남겨 깔끔한 형태의 결과를 출력합니다.
그 결과, 두 문서의 가격인 10.5와 9.5가 합산된 20이라는 최종 가격을 확인할 수 있습니다. 이처럼 $cond와 $group을 조합하면 조건에 따라 고유 속성을 식별하고 원하는 집계 결과를 손쉽게 도출할 수 있습니다.