mongo db 에서 조인하는 법 (lookup)

김재영·2021년 7월 29일
0

Collection "project":

{
    "_id" : ObjectId("6102780c27474af56cf6734b"),
    "channel" : "instagram",
    "status" : "new",
    "analysis_type" : "detail",
    "batch_ids" : [ 
        "6102780c27474af56cf6734d", 
        "6102780d27474af56cf6734f", 
        "6102780d27474af56cf67351", 
        "6102780e27474af56cf67353", 
        "6102780e27474af56cf67355", 
        "6102780e27474af56cf67357"
    ]
}

Collection "batch":


{
    "_id" : ObjectId("6102780c27474af56cf6734d"),
    "keyword" : {
        "keyword" : "tomato",
        "keyword_type" : "hashtag"
    },
    "channel" : "instagram",
    "post_datetime" : ISODate("2021-07-29T18:42:36.306Z"),
    "analysis_type" : "detail",
    "status" : "new",
}

project 콜렉션은 여러개의 batch 를 가질 수 있음. project 의 batch_ids 필드에 프로젝트가 포함하고 있는 배치가 무엇인지 입력해 두었음. batch_ids 의 각각의 요소들은 배치의 _id값.

이 때 이 두가지 콜렉션을 한 번에 보고자 함.
내가 원하는 결과물 은 다음과 같다:

{
    "_id" : ObjectId("6102780c27474af56cf6734b"),
    "channel" : "instagram",
    "status" : "new",
    "analysis_type" : "detail",
    "batch_ids" : [ 
        {
         "_id":ObjectId("6102780c27474af56cf6734d"),
         "status":"new"
        },
        {
         "_id":ObjectId("6102780d27474af56cf6734f"),
         "status":"new"
        },
        {
         "_id":ObjectId("6102780d27474af56cf67351"),
         "status":"new"
        },
        {
         "_id":ObjectId("6102780e27474af56cf67353"),
         "status":"new"
        },
        {
         "_id":ObjectId("6102780e27474af56cf67355"),
         "status":"new"
        },
        {
         "_id":ObjectId("6102780e27474af56cf67357"),
         "status":"new"
        },
    ]
}

몽고디비에서 조인을 하기 위해서는 lookup 을 사용한다.

  • from : 조인대상 콜렉션 이름
  • let : 파이프라인에서 사용할 변수를 선언한다.
  • map : batch_ids 필드가 string 타입이기 때문에 ma 이용해서 objectId 로 변경해준다.
  • pipeline : $$를 이용해서 let 에서 선언한 batchObjectIds 를 선택함
  • match : $를 통해 조인대상할 콜렉션의(batch collection) _id 값을 가져온다.
    -> let 에서 선언한 batchObjectIds 배열 내에 있는값 매칭됨
  • project 함수를 이용해서 매칭된 도큐먼트 필드를 필터링 ex) 보고싶은 필드:1
  • 마지막으로 as 를 이용해서 어떤 필드값으로 외래필드를 볼지 정하면 됨.
db.project.aggregate([
  {
    "$lookup": {
      "from": "batch",
      "let": {
        batchObjectIds: {
          $map: {
            input: "$batch_ids",
            as: "batch_id",
            in: {
              "$toObjectId": "$$batch_id"
            }
          }
        }
      },
      "pipeline": [
        {
          $match: {
            $expr: {
              $in: [
                "$_id",
                "$$batchObjectIds"
              ]
            }
          }
        },
        {
          $project: {
            _id: 1,
            status: 1
          }
        }
      ],
      "as": "batch_ids"
    }
  }
])

자세한 내용은 공식문서 참고

0개의 댓글