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

MongoDB GroupBy로 상태(Status)별 문서 분류하기

MongoDB에서는 aggregate() 메서드를 사용하여 특정 상태 값에 따라 문서를 그룹화하고 분류할 수 있습니다. 이 글에서는 $group, $cond, $setDifference 연산자를 조합하여 Status 필드 값을 기준으로 문서를 'done'과 'notdone' 두 그룹으로 나누는 방법을 단계별로 살펴보겠습니다.

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

먼저 예제로 사용할 컬렉션을 만들고 문서를 삽입합니다.

> db.demo149.insertOne({"Status":40});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e350386fdf09dd6d08539c4")
}
> db.demo149.insertOne({"Status":40});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e350388fdf09dd6d08539c5")
}
> db.demo149.insertOne({"Status":50});
{
   "acknowledged" : true,
   "insertedId" : ObjectId("5e35038afdf09dd6d08539c6")
}

2. find()로 전체 문서 확인하기

find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 조회할 수 있습니다.

> db.demo149.find();

위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.

{ "_id" : ObjectId("5e350386fdf09dd6d08539c4"), "Status" : 40 }
{ "_id" : ObjectId("5e350388fdf09dd6d08539c5"), "Status" : 40 }
{ "_id" : ObjectId("5e35038afdf09dd6d08539c6"), "Status" : 50 }

3. aggregate()로 상태별 그룹화 쿼리 작성

이제 핵심인 집계 쿼리입니다. $group 단계에서 _idnull로 지정하면 전체 문서를 하나의 그룹으로 묶을 수 있고, $push$cond를 함께 사용하면 조건에 맞는 문서만 배열에 담을 수 있습니다. 이후 $project 단계에서 $setDifference를 적용하면 조건에 해당하지 않아 삽입된 false 값을 제거할 수 있습니다.

> db.demo149.aggregate([
...    {
...       "$group": {
...          "_id": null,
...          "done": {
...             "$push": {
...                "$cond": [
...                   { "$eq": [ "$Status", 40 ] },
...                   { "_id": "$_id", "Status": "$Status" },
...                   false
...                ]
...             }
...          },
...          "notdone": {
...             "$push": {
...                "$cond": [
...                   { "$eq": [ "$Status", 50 ] },
...                   { "_id": "$_id", "Status": "$Status" },
...                   false
...                ]
...             }
...          }
...       }
...    },
... {
...    "$project": {
...       "_id": 0,
...       "done": {
...          "$setDifference": [ "$done", [false] ]
...       },
...       "notdone": {
...          "$setDifference": [ "$notdone", [false] ]
...          }
...       }
...    }
... ]);

쿼리 동작 방식 정리

  • $cond: Status가 40이면 'done' 배열에, 50이면 'notdone' 배열에 해당 문서를 추가합니다. 조건에 맞지 않으면 false가 임시로 들어갑니다.
  • $setDifference: 배열에서 false 값을 제거하여 실제 조건에 일치하는 문서만 남깁니다.
  • $project (_id: 0): 결과에서 자동 생성된 그룹 ID 필드를 제외하고 'done'과 'notdone'만 출력합니다.

4. 실행 결과

위 집계 쿼리를 실행하면 Status 값에 따라 문서가 두 그룹으로 깔끔하게 분류된 것을 확인할 수 있습니다.

{
   "done" : [
      { "_id" : ObjectId("5e350386fdf09dd6d08539c4"), "Status" : 40 },
      { "_id" : ObjectId("5e350388fdf09dd6d08539c5"), "Status" : 40 } ], "notdone" : [
      { "_id" : ObjectId("5e35038afdf09dd6d08539c6"), "Status" : 50 }
   ]
}

이처럼 MongoDB의 애그리게이션 파이프라인을 활용하면 별도의 애플리케이션 로직 없이도 데이터베이스 차원에서 조건별 문서 분류를 효율적으로 처리할 수 있습니다.