被MongoDB用Aggregate暴打的後端小菜雞日記-day9-$lookup將兩個collection的資料合併(上)

鰻魚燒
Sep 8, 2022

一開始在使用MongoDB的時候,總是在想它不像MySQL關聯資料庫一樣,可以做兩張資料表的join,要把兩個collection的資料,分別搜尋自己組合好麻煩,還是MySQL比較好。

直到我遇見了$lookup,它的作用和關聯資料庫的join類似,可以將兩個collection資料合併再一起,傳遞給下一個pipeline,它的寫法分成兩種,一種是今天要介紹的寫法,比較陽春一點,會把join的collection資料欄位全部加進來。

另一種寫法比較複雜一點,但可以在$lookup內寫pipeline,將要join進來的collection資料先運算,再做join的動作。

此外在進行$lookup,如果兩個collection的資料數量都很多,強烈建議一定要設索引(index),不然搜尋資料的效能會變得超差。

Photo by Maksym Kaharlytskyi on Unsplash

例如:學生的成績這個collection有3000筆資料,而學生基本資料的collection有600筆資料,兩個collection做$lookup搜尋資料,在沒有建立索引的情況下,會搜尋資料3000×600次,十分的沒效率。

假設現在我們有學生成績資料(score)三筆

學生的個人資料(profile)三筆

如果老師想要將兩張資料表合併,製作成績單列印給學生帶回去,會用以下指令。

得到的資料會如下

join加入的資料會用陣列包裹起來,如果想要讓資料再精簡一點,只取我們想要的欄位,必須在寫一個$project$addFields的pipeline,整理要回傳的資料欄位。

例如:老師成績部分只想保留數學和英文成績,個人資料只想要留下姓名和座號。
我們可以利用$arrayElemAt取得特定陣列的元素,後面接一個陣列,第一個item填要取資料的陣列欄位名稱,第二個item填要取的元素位置。

回傳的資料會是

ps.如果很想知道每一個pipeline處理完的資料,到底會長怎樣,可以自己console.log()出來看一下。

--

--

鰻魚燒

剛轉職成後端工程師的小菜雞,分享自己的學習筆記