DAY7 MongoDB 資料更新(Update)
更新(update)
資料更新(Update)如同寫入或刪除一樣,都是相同 Pattern,差別是條件比較多。
1 | db.collection.updateOne(filter, update, options) |
兩者基本上是一樣的,相信你們看完前面的 insertOne, insertMany, deleteOne, deleteMany 都有感覺了。
filter 是過慮條件,也就是你要找到欲更新文件的條件。
options 這個是更新的設定選項,在剛開始會用不到太多項目,只有一個要特別注意,就是 upsert,通常我們會設定為 true,這也是 MongoDB 很方便的地方。顧名思義,就是當欲更新的文件如果存在時,進行 update,當找不到這比文件時,就進行 insert。
UpdateOne Demo - 1
馬上來個範例,我們先查詢,確保沒有該文件,接著執行 upsert:true 的 updateOne 語法:
1 | db.upsert.sample.find() |
可以看到 upsert.sample collection 起初是沒有資料的,我使用了 find(),不帶任何參數的查詢,查不到任何資料。
接著再一個 updateOne 的內容裡,執行後直接新增比資料,透過回傳的參數也可以看到 upsertedCount 數量為 1。
insertedId:本次執行結果,寫入的 ObjectId 清單matchedCount:本次執行結果,符合查詢條件的文件數量modifiedCount:本次執行結果,符合查詢條件且更新的文件數量upsertedCount:本次執行結果,進行 upsert 的文件數量
接著將這次的 updateOne 語法來拆開來看:
1 | db.upsert.sample.updateOne( |
可以看到三組大括弧 {},這分別對應了上面提到的 filter, update 與 options。
filter:這邊我們直接不帶條件,想進行全部文件的 updateupdate:我們設定 name 欄位的值為 try upsert,$set 是 MongoDB 的 operator 之一,這個我們之後再講解,先忍著略過它。options:這次 updateOne 中,設定值設定upsert為true,代表找不到資料就寫入。設定還有writeConcern,collation和hint等,這個會在後面再講解,現在提就太深入了。
UpdateOne Demo - 2
這次我們準備幾筆符合查詢條件的文件,使用 UpdateOne 看看會發生什麼事情。
資料庫內有三筆名為 Arthas 的資料
1 | db.upsert.demo2.find() |
執行 updateOne,將名為 Arthas 的資料欄位改為 ErrorName
1 | db.upsert.demo2.updateOne({'name':'Arthas'}, {$set:{'name':'ErrorName'}}) |
可以看到執行後,再次查詢,只會有第一筆被修改,因為我們執行的是 updateOne。
那為什麼第一筆不是_id為9d4 或 9d5 結尾的資料呢?因為 MongoDB 採用的是 natural sort,在這個情況下就是 9d3 這一筆。我們會在後面的天數講到 natural sort,這是一個非重要的概念。
replaceOne
replaceOne,找到符合條件的文件,直接整份文件取代。
replaceOne 用法與 Update 高度相近,來看看它的長相:
db.collection.replaceOne(filter, replacement, options)
- filter: 設定的查找文件條件
- replacement: 新的文件內容
- options: 設定值,與 update 的幾乎一樣。
我們來嘗試找到一個文件,{name:'Thrall'},將它改成下面這樣子
1 | { |
1 | db.upsert.demo2.find() |
可以看到新的內容已經取代上去,特別要注意的是 _id 並沒有任何異動,即便它不是客製化的 _id,仍然不會改變,因為這個操作是取代文件內容,不會影響它本身的 key。
附帶一提,replaceOne 如同上面所說,設定值是幾乎一樣的,所以也有 upsert 功能,這邊就不再示範了,結果會與 update 一樣。