Mongodb aggregate lookup

박종혁·2021년 10월 20일
0

$lookup

RDB의 join개념

quiz라는 col에서 다음과 같은 aggregate 실행

{
  from: 'quiz_users',
  localField: '_id',
  foreignField: 'quiz_id',
  as: 'participated'
}

===

{
  from: 'quiz_users',
  let:{original: "$_id"},
  pipeline:[
    {
      $match: {
        "$expr": {
          $eq: 
            ["$$original", "$quiz_id"],
        }
      }
    }
  ],
  as: 'participated'
}

quiz_user col과 join할때 _id는 primary key, quiz_id는 foreign key로 동작
이를 통해 join된 doc은 participated안에 배열 형태로 return

$lookup내의 pipeline내에서는 localField와 foreignField를 구분하지 않음
그래서 변수 할당후 접근하는 방법으로 키값에 접근
2번의 let을 사용한 방법은 $lookup내에서 변수선언
_idoriginal이라는 변수에 할당
이를 통해 pipeline안에서 할당된 변수에 접근 가능
$match안에서 변수를 바로 사용할 수 없기 때문에 $expr사용
$eq로 동일한 값 리턴시키고 pipeline종료
as에서 participated로 객체 배열 받음

원하는 기능

제작중인 서비스 내에 퀴즈가 존재하고 유저들은 퀴즈에 참여(중복참여 불가)
서비스에 로그인한 상황에서 퀴즈 목록을 불러올때 내가 참여한 퀴즈에 마킹해주기 위한 데이터 형태를 쿼리 목표로 함

quiz - 퀴즈 col
quiz_user - 퀴즈id, 유저id, 퀴즈 참여 데이터 포함하는 doc col

quiz col에서 aggregate 수행
match로 원하는 quiz 선택
{ content_id: ObjectId('616f8393aa1f5b1043715059') }

aggregate로

{
  from: 'quiz_users',
  let:{original: "$_id"},
  pipeline:[
    {
      $match: {
        "$expr": {
          $and: [
            {$eq: ["$$original", "$quiz_id"]},
            {$eq: ["$user_id", ObjectId('616f84f4aa1f5b104371505d')]}
          ]
        }
      },
      // quiz_id: ObjectId('616f84f4aa1f5b104371505d')
    }
  ],
  as: 'participated'
}
profile
메모 메모

1개의 댓글

comment-user-thumbnail
2022년 1월 6일

낯익은 이름에 다시봣더니.. 종혁님 잘 지내시나요 ㅋㅋㅋ
회사에서 일하다가 리서치하는데 종혁님 글이였네요 ㅋㅋㅋ

답글 달기