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 단계에서 _id를 null로 지정하면 전체 문서를 하나의 그룹으로 묶을 수 있고, $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의 애그리게이션 파이프라인을 활용하면 별도의 애플리케이션 로직 없이도 데이터베이스 차원에서 조건별 문서 분류를 효율적으로 처리할 수 있습니다.