nodeJS

관련있는 Object를 서로 연결시켜주기. populate() - 1

변기원 2022. 2. 16. 12:50

유튜브를 생각해보면 동영상은 owner를 가지고 있다. 누가 올린 영상인지 알수있다.

그리고 user는 본인이 올린 영상을 전부 알수있다. 

즉 user는 video를 가지고 있고, video는 owner를 가지고 있다.

video는 단 한명의 user를 owner로 가지고

user는 다수의 video를 가진다.

 

일단 video model 에 owner 객체를 연결해보자

video model

videoSchema에 owner를 추가하는데 type이 특이하다.

String이나 Date, Number처럼 javascript에서 제공하는 type이 아니라 mongoose의 기능을 이용해서

ObjectId를 넣는다. owner는 objectId를 가질것이고 User모델 object의 id를 참고로 불러올것이다.

 

자 여기까지 마쳤다면 video model이 처음 생성되는 곳으로 가면 된다.

어디였더라? video 를 처음 업로드 하는 순간 생성되니까 videocontroller의 postUpload이다.

video controller

Video 모델이 만들어지고 저장되는 Video.create 부분에 owner를 추가했다. 그리고 objectId는 현재 세션에 연결된 user의 id를 넣었다. 왜냐하면 지금 로그인하고 있는 user가 업로드를 하고 있는 상황이니까, 지금 session의 user가 업로드 하는 video의 owner가 확실하다. 드디어 owner가 들어갔으니 video를 한번 콘솔에 찍어볼까?

터미널

owner에 id가 들어갔다. 이것으로 video가 어떤 user의 id와 일치하는지 안하는지 정도를 판단할 수 있게 되었다.

 

이런경우를 생각해보자

웹페이지

동영상 하단에 동영상 owner의 username을 출력해서 보여주고 싶다. 유튜브도 그렇듯이?

그럼 template에 user를 보내줘야 한다. user는 db에서 찾아야 한다.

video controller

user의 _id가 해당 video의 owner와 같은 user를 찾아서 template에 user로 변수를 보내줘야한다.

근데 이렇게 하면 db가 두번 불러지니까 populate를 이용하면 더 빠르고 코드도 적게 쓸 수 있다. 

video controller

video의 owner에 populate를 적용했다. 콘솔에 video를 찍어서 위와 비교해보자

터미널

엄청 신기하다.. video data의 owner부분에 objectId를 참고하여 User data가 들어가 있다..

이렇게 되면 굳이 user를 db에서 불러올 필요가 없다. 어차피 video owner에서 전부 참고할수 있으니까.

template에서 간편하게 video.owner를 찾으면 된다. 한번 pug template을 보자

watch.pug

원래같았으면 db에서 user를 찾아서 user를 변수로 받아서 user.username으로 입력했을 부분에 video.owner.username이 들어가 있다. populate를 가지고 video.owner에 object를 불러왔기 때문에 굳이 db를 찾지 않고 저렇게 작성해도 제대로 된 값이 들어간다.

 

Owner는 한명이니까 이렇게 했다면, user는 다수의 video를 소유할테니 객체가 많아질것이다. 배열을 써보자. 

자세한건 그건 다음 글에서 !