사람은 망각의 동물이다

까먹지 말고 기록하자

mongodb

$lookup 사용하기

Parker Park 2021. 7. 27. 19:10

RDBS에서 테이블 A와 테이블 B의 데이터를 통합해서 보여주거나 조회할 때, join 을 사용한다.

mongoDB 에서 RDBS의 join 처럼 두개 이상의 컬랙션의 데이터를 통합해서 조회할 때, $lookup 파이프를 사용할 수 있다.

$lookup

  1. $lookup은 현재 컬랙션을 기준으로 다른 컬렉션의 정보를 입력하고 join 할 수 있다.
  2. $lookup은 mongoDB의 aggregate 에서 사용할 수 있는 파이프다.
{
   $lookup:
     {
       from: <collection to join>,
       localField: <field from the input documents>,
       foreignField: <field from the documents of the "from" collection>,
       as: <output array field>
     }
}

예제

다음처럼 두 컬렉션이 주어질 때, School 정보와 함께 Student를 조회하고 싶을 때, $lookup 을 활용할 수 있다.

Student 컬렉션

{
    _id: <ObjectId>,
    name: <Student Name>,
    school: <ObjectId>
}

School 컬렉션

{
    _id: <ObjectId>,
    name: <School Name>,
    location: <School Location>
}

쿼리

>>> db.student.aggregate([{
    '$lookup': {
        from: 'school',
        localField: 'school',
        foreignField: '_id',
        as: 'school'
    }
}])

[{'name': 'A', 'school': [{'name': 'SchoolA', 'location': 'hankuk'}]},
{'name': 'B', 'school': [{'name': 'SchoolB', 'location': 'english'}]},
{'name': 'C', 'school': [{'name': 'SchoolB', 'location': 'english'}]}]

tip

$lookup은 결과를 배열로 담기 때문에 1:1 매핑인 경우 $unwind 까지 해줘야 값에 접근하기 편하다.

>>> db.student.aggregate([{
    '$lookup': {
        from: 'school',
        localField: 'school',
        foreignField: '_id',
        as: 'school'
    }
}, {
    '$unwind': {
        path: '$school'
    }
}])

[{'name': 'A', 'school': {'name': 'SchoolA', 'location': 'hankuk'}},
{'name': 'B', 'school': {'name': 'SchoolB', 'location': 'english'}},
{'name': 'C', 'school': {'name': 'SchoolB', 'location': 'english'}}]