본문 바로가기
컴퓨터공학 기초/데이터베이스

[MongoDB] group 쿼리를 사용하여 Array<Object> 데이터 그룹화하기

by 상용최 2022. 7. 3.
반응형

MongoDB 를 사용하다보면 Array<Object> 형식인 데이터를 그룹화 해야할때가 있습니다.

예를들어 아래와 같은 데이터가 있고 user 의 type 별 평균값을 알고싶다고 가정해봅시다.

{
  "id" : 1,
  "userId" : 1,
  "items" : [
    {"type" : 1, "value" : 1},
    {"type" : 2, "value" : 2},
  ]
},
{
  "id" : 2,
  "userId" : 1,
  "items" : [
    {"type" : 1, "value" : 3},
    {"type" : 2, "value" : 4},
  ]
}

 

눈으로 보면 굉장히 쉬워보입니다.

userId 로 group 한 후 타입별로 평균값을 내기만하면됩니다.

 

이 쉬워보이는 작업을 필자는 오랜시간 삽질한후에 결과를 낼 수 있었습니다.

혹시나 필자와 비슷한 상황이신분들이 계시면 도움을 드리고자 이 게시글을 작성하게됐습니다.

 

본론에 들어가기 전 힌트를 드리자면 aggregation, unwind, group 을 활용하여 이 문제를 해결할 수 있습니다.

 

먼저 가장먼저 해야할일은 unwind 를 활용하여 list 를 쪼개주어야 합니다.

    {
        $unwind:  {path : "$items" }
    }

 

그 후 group을 활용하여 그룹화해줍니다.

이 때 주의할점은 group key 를 userId 만 잡으면 안되고 items.type 과 함께 잡아야 합니다.

"$group" : {
    _id: {
        "userId" : "$userId",
        "type": "$items.type"
    }
}

 

 

그리고 type 별 평균을 구하기위해 avg 명령어를 활용하여 평균을 구해줍니다.

"$group" : {
    _id: {
        "userId" : "$userId",
        "type": "$items.type"
    },
    "avg": { "$avg" : "$items.value" }
}

 

종합해보자면 이런쿼리가 나온다.

db.getCollection('Example').aggregate([
    {
        $unwind:  {path : "$items" }
    }
    ,   
    {
        "$group" : {
            _id: {
                "userId" : "$userId",
                "type": "$items.type"
            },
            "avg": { "$avg" : "$items.value" }
        }
    }
])
반응형

댓글