被MongoDB用Aggregate暴打的後端小菜雞日記-day15-$merge 將資料寫回資料庫

鰻魚燒
Sep 14, 2022

--

當你好不容易寫好一連串的aggregate,想要將整理好的資料寫回資料庫內,這時候就可以使用$merge將資料寫入,使用上必須特別注意,一定要放在pipeline最後一個位置,不然會直接噴錯誤訊息,「MongoError: $merge can only be the final stage in the pipeline」。

讓我們延續昨天的範例,原本有學生的成績資料(隔壁小王成績太高,有被我調低一點XD)

老師決定幫學生進行加分,加分方式是數學成績乘上1.2,英文的分數乘上1.5,並且要將調整完的分數,寫回去資料庫內,這時會使用到以下指令。

此時aggregate跑完會回傳空陣列,如果想看資料是否被正確寫入,可以使用find把學生的資料撈出來檢查一下。

$merge其實有很多細節設定可以拿出來講

  1. 如果into設定要寫入的collection是原本不存在的,MongoDB會自動幫你建立一個新的collection
  2. on其實可以設定多個欄位,來取匹配原本資料庫的文件,看要取代掉哪一筆資料。

例如:on: ["_id", "name]代表寫入的資料_idname這兩個欄位都要和原本資料_idname欄位值都相同,才會取代這筆資料,否則會新增一筆全新資料。

Photo by Bekky Bekks on Unsplash

必須特別注意的是,選取的欄位一定要有 unique index,不然終端機會噴出錯誤訊息「MongoError: Cannot find index to verify that join fields will be unique」

ps.良心建議,直接寫on: "_id"會比較間單,因為MongoDB本身就會幫你建立好_id的unique index,完全不需要額外設定。(本人為了測時這個設定,被unique index搞了一整個上午)

3. whenMatched除了replace(取代),還有其他的設定可以選擇,例如:keepExisting可以保留原本的資料,不會被取代。

4. whenNotMatched除了insert(插入),還有其他的設定可以選擇,例如:discard不會插入新的資料進入collection。

如果想要在更深入了解$merge的細節設定,可以參考官方文件

--

--

鰻魚燒

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