前言:從基本操作到成熟應用
在前面章節中,我們已經掌握 MongoDB 的查詢技巧,瞭解如何透過運算子、條件組合與映射來篩選所需資料。本章更進一步,從查詢延伸至新增(Insert)、更新(Update)與刪除(Delete)等核心 CRUD 操作,並介紹批次寫入(Bulk Write)這類提升效率的進階技巧。
這些操作動作(新增、更新、刪除)是應用程式後端邏輯中必不可少的部分。無論是電商後台管理庫存與訂單狀態、銀行後台調整帳戶餘額、社交平台更新用戶資訊或聊天記錄,相關的新增、更新、刪除行為遍佈各種情境。本章不僅介紹語法與運算子,更進一步透過實戰範例(如銀行帳戶管理系統)示範如何將這些技巧整合到程式碼中,並結合前面章節的查詢概念,達到更加成熟的應用。
一、技術背景與基礎原理
新增(Insert)操作的意義
在傳統 RDBMS 中,我們透過 INSERT INTO 將新資料行插入表格中,預先定義的 Schema 確保資料格式一致。MongoDB 則不用預先定義 Schema,開發者可直接在集合(Collection)中插入文件(Document)。此彈性讓開發初期能快速試驗與迭代。
新增一筆資料在 MongoDB 中透過 insertOne 或 insertMany 實現。對應關聯式資料庫來說,不同處在於文件可以具備不完全相同的欄位集合,使前期開發更靈活。
更新(Update)操作的設計考量
更新動作在實務中更常見。例如,使用者資料須更新地址、訂單狀態需從「已下單」變為「已出貨」,或電商商品價格變動。MongoDB 提供 Update 運算子($set、$inc、$mul、$rename、$max、$min、$unset、$currentDate)讓我們精準控制對欄位所需的變更,無需重新寫整筆文件。
透過這些運算子,MongoDB 更新操作能一次完成多個欄位的微調。例如,$inc 適合調整數值欄位(如貨幣餘額或庫存),$set 設定欄位新值,$unset 刪除不再需要的欄位。如此一來,開發者可輕鬆回應需求變化,而不用進行繁瑣的整筆文件重寫。
刪除(Delete)操作與清理資料
在任何系統中,資料刪除是必要的,無論是使用者要求刪除帳號資料,或系統定期清除過期紀錄。MongoDB 的 deleteOne 與 deleteMany 提供單筆與多筆刪除能力,並可搭配查詢條件確保刪除正確文件。不必像 RDBMS 般需依靠外鍵或嚴格限制,也不需 JOIN 來找到相關紀錄,因為MongoDB是文件導向而非關聯式架構。
批次寫入(Bulk Write)的效率優勢
若有大量更新或新增操作,若逐筆執行,每次都要與資料庫建立溝通並處理請求,成本相對高昂。Bulk Write 將多個操作(如多筆insertOne、updateOne或deleteOne)合併在一次請求中傳送給資料庫,減少網路往返次數,大幅提升效率。
此特性在需要同時更新成千上萬筆資料的情境特別有用,例如訂單系統批量更新訂單狀態、財務系統批量更新交易記錄。透過 Bulk Write,可縮短系統反應時間並節省運算資源。
二、從範例延伸到實務需求
書籍借閱紀錄範例
以圖書館紀錄為例,我們透過MongoDB的insertOne 新增一本書籍紀錄、updateOne 更新借閱人、deleteMany 刪除某個人借過的所有書籍紀錄。這對實務應用來說十分常見,如電商後台中更新單筆商品資訊、刪除特定類別商品、或新增新品。
銀行帳戶餘額更新範例
在範例中,我們使用 $inc 遞增或遞減帳戶餘額、$mul 調整匯率後的金額、$rename 統一欄位名稱、$unset 刪除不再需要的欄位、$currentDate 更新最後修改時間。這些操作在金融、物流、會員系統中相當實用:
$inc 適合處理餘額、庫存、計數器等數值型欄位。
$currentDate 可記錄最新修改的時間戳,有助於審計、記錄和日後查詢。
陣列更新運算子與實務應用
陣列運算子($push、$pop、$pull、$each、$position)讓我們可輕鬆對清單、記錄、標籤、留言等陣列資料結構進行增減。例如:聊天系統中新增一則訊息至對話紀錄尾端;留言板依序插入新留言;從使用者的興趣標籤中移除不再適合的標籤。
透過這些運算子,我們可維護各種以陣列為單位的欄位資訊(如一篇文章的標籤列表、一個使用者的好友清單),而不必整筆文件重寫。
批次寫入(Bulk Write)的加值應用
在飲料店批量售出多種飲品的範例中,bulkWrite 將三個updateOne合併成一個請求,效能表現更優。若以此延伸至大型電商網站,每分每秒可能有數萬筆訂單狀態需要更新,使用 Bulk Write 可顯著降低伺服器負載與延遲。
此外,企業在年度結算或年度庫存盤點時,可透過 Bulk Write 實現大規模資料更新動作,一次完成多筆補貨、價格調整,減少前後端等待時間並提升用戶體驗。
三、組織與開發團隊的實務操作策略
團隊協作與程式碼維護
將 MongoDB 操作(新增、更新、刪除)封裝於後端服務的 Repository 或 Data Access Layer 中,可提高程式碼可維護性。團隊成員不必記憶所有運算子細節,只要呼叫封裝好的方法(如 repository.AddBook()、repository.UpdateStock()),即可完成操作。
在 CI/CD 流程中,可撰寫單元測試(Unit Test)針對更新與刪除邏輯進行檢驗。測試確保程式碼在版本迭代時維持正確性與穩定度,避免上線後發生嚴重資料錯誤。
版本控制與審查(Code Review)
當開發者在程式中新增或調整 MongoDB 操作程式碼時,可透過 Git 版本控制與 Code Review 確保更新運算子使用正確。例如,審查時可檢查 $inc 運算子是否應用於正確欄位,$set 是否確保資料一致性,$unset 是否真的不會移除關鍵欄位。
團隊領導或資深工程師可在Code Review中提供建議,如將複雜的更新邏輯分解成小塊,或使用 Builders 類別建立可重複使用的 Filter 與 Update 模組。
資安與資料品質管控
在實務中,資料更新與刪除必須嚴格控管權限與條件。後端服務可加上認證與授權機制,確保只有具備適當角色與權限的用戶可進行特定刪除或更新操作(例如只有管理員可刪除整批數據,普通用戶僅可更新自己的紀錄)。
使用欄位更新運算子前,若資料格式不符合預期(例如數值欄位存入字串),則需先行驗證、清洗資料,以免更新運算子出現預期外的結果。
四、測試與效能優化
效能測試與索引策略
就像查詢語法會受益於索引,更新與刪除操作也可受益於適當索引配置。為了提高 update 與 delete操作的速度,務必在執行頻繁檢索的欄位上建立索引(如使用者ID、商品ID)。
若批次操作(Bulk Write)具備大量更新,應在測試環境中先進行壓力測試,確保資料庫可在預定時間內完成大量更新。若發現效能不足,可嘗試建立更多或更合適的索引,或透過水平擴展(Sharding)提升效能。
日誌與偵錯
在實務場景,日誌紀錄(Logging)與偵錯工具對維運相當重要。每次更新或刪除動作都可記錄在日誌中,包括執行的條件、變動結果與執行時間,能協助團隊排查問題與進行審計。
遇到資料不一致或怪異行為時,可使用 Compass 或 Mongosh 進行手動檢查,並結合 explain() 分析查詢計畫與更新計畫,以找出潛在瓶頸。
五、延伸應用與未來趨勢
結合 Aggregation Pipeline
若對批量更新後的資料進行進一步分析,可結合 Aggregation Pipeline 進行聚合、分組與計算。舉例而言,更新商品訂價後可立即透過 Aggregation 查詢統計,了解整體價格分布,快速決策接下來行銷策略。
雲端與微服務架構下的應用
在微服務與雲端化的生態中,MongoDB 更新與刪除操作可由不同服務獨立執行。每個微服務擁有自己的 MongoDB 集合與邏輯,使用 Bulk Write 執行大量更新任務,同時與其他微服務協同運作。雲端平台(如 MongoDB Atlas)提供全球分布式部署,更可讓跨區域更新同步進行。
與機器學習、大數據平台結合
未來,隨著資料分析需求增長,機器學習與大數據平台將持續整合 MongoDB。更新與刪除動作若能快速完成,代表系統可保持高速吞吐量與即時性。在建模、特徵工程過程中,透過快速更新標記、刪除無用的訓練資料,能有效優化分析流程。
六、組織策略與人員培訓
人員培訓與最佳實務
組織可透過內部文件、範本程式碼(boilerplate)與工作坊,讓開發者熟悉 MongoDB 新增、更新、刪除操作規範與模式。提供詳細範例,使新進工程師能迅速掌握運算子如 $inc、$set、$rename 的用法,以及何時使用 Bulk Write。
程式碼與資料庫治理
資料更新、刪除涉及公司核心資產,需嚴格定義治理策略。對關鍵欄位變更要審批,對大量刪除操作要有回滾機制或預備備份方案。訂立程式碼規範,要求在Merge前對更新邏輯進行 Code Review,降低錯誤風險。
版本管理與持續學習
MongoDB 不斷更新版本與功能特性。團隊應持續追蹤新版本運算子與 Bulk Write改良之處,定期調整策略與程式碼提升效率與安全。
七、總結與展望
本章介紹的新增、更新、刪除、批次寫入操作是 MongoDB 實務應用的關鍵一環。透過這些技巧,我們可實現:
更彈性的資料維護:依需求快速新增新書籍紀錄、修改訂單狀態或調整商品價格。
效能優化:Bulk Write 減少對資料庫的呼叫次數,節省資源與時間。
結合前面章節的查詢技巧:搭配查詢運算子與映射,開發者可同時控制欄位與條件,快速達成複雜的資料處理需求。
本章末實作的「銀行帳戶管理系統」範例,將這些操作整合起來,並在 C# 與 Visual Studio 2022 環境下執行,使開發者實際感受到 MongoDB CRUD(新增、讀取、更新、刪除)全套流程的靈活度與高效率。
展望未來,隨著 MongoDB 生態圈持續演進,更多更新與刪除運算子、批次操作技巧以及和雲端微服務整合的特性必將出現。對企業而言,熟練本章技巧有助於快速回應市場變化,提升產品競爭力,並為更高階的分析、決策與自動化奠定穩固基礎。
總體而言,本章不僅傳授了 MongoDB 的新增、更新、刪除技術,更提供讀者思考這些操作在組織與產業中的實際價值,幫助讀者從開發者角度轉向更廣闊的產品與商業視野,實踐真正落地的高效資料管理方案。
第7章 MongoDB 基本操作:新增、更新與刪除
7.1 觀念說明
在前面章節中,我們已透過 MongoDB 的指令或 GUI 工具(如 MongoDB Compass)學習了查詢資料的多種方式。在本章中,將進一步探討 MongoDB 的新增、更新與刪除操作。為了更直觀地比較關聯式資料庫與 MongoDB 在新增、更新、刪除語法上的差異,我們以「書籍借閱紀錄」為例。
在關聯式資料庫中,插入、更新、刪除資料主要透過 SQL 指令(INSERT、UPDATE、DELETE)完成;而在 MongoDB 中,則是透過對集合(Collection)和文件(Document)的操作,以及各種更新、刪除運算子的組合來達成。下圖(圖7-1)示意關聯式資料庫與 MongoDB 在資料儲存格式和操作語法上的差異。
新增語法的比較範例:
-
關聯式資料庫:
-
MongoDB:
更新語法的比較範例:
-
關聯式資料庫:
-
MongoDB:
刪除語法的比較範例:
-
關聯式資料庫:
-
MongoDB:
透過上述比較,我們可清楚看出 MongoDB 在操作語法與資料結構上與關聯式資料庫的不同。本章將逐步說明 MongoDB 中的新增、更新與刪除操作,以及相關的更新運算子與批次寫入(Bulk Write)技巧。
7.2 MongoDB 新增操作
範例7-1:在 scores 集合中新增一筆學生考試資料
假設有一個 scores 集合,儲存學生考試資料的文件(Document)包含:編號(_id)、學生編號(studentNumber)、學生姓名(studentName)與分數(score)。
-
匯入資料:
使用 Compass 進入 scores 集合,點選「ADD DATA→Insert document」,輸入:按下「Insert」後完成新增。
-
查詢結果:
在 scores 集合中可立即看到剛剛新增的文件。
7.3 MongoDB 刪除操作
範例7-2:刪除全部學生考試資料
- 若要刪除 scores 集合中的所有資料,可直接點選「DELETE」按鈕。
- 確認刪除後,集合中無任何文件。
若需指定刪除某筆資料(如 id為001 的考試資料),可在 Query 欄位中輸入 {_id:"001"} 後查詢並刪除。
7.4 MongoDB 更新操作
在實務中,更新資料是常見需求。例如:銀行資料庫需更新客戶帳戶餘額,或電商後端需更新商品庫存數量。MongoDB 提供許多更新運算子,根據資料結構可分為「欄位(Field)更新運算子」與「陣列(Array)更新運算子」兩類。
欄位更新運算子
| 運算子 | 功能說明 |
|---|---|
| $inc | 對欄位執行遞增/遞減操作 |
| $mul | 對欄位執行乘法運算 |
| $set | 設定欄位的新值 |
| $rename | 更改欄位名稱 |
| $max | 若欄位值低於門檻,則提升至門檻值 |
| $min | 若欄位值高於門檻,則降低至門檻值 |
| $unset | 刪除欄位 |
| $currentDate | 將欄位設為當前日期或時間 |
範例7-3:更新銀行帳戶餘額
在 accounts 集合中有帳戶資料,如下欄位:id, name, currency(type, cash, lastModified)。
情境:小明領出1000元,需將其帳戶餘額扣除,並更新最後修改時間。
步驟:
- 查詢小明的 TWD 帳戶:
Query:{name:"小明","currency.type":"TWD"} - 更新指令中使用
$inc遞減餘額$currentDate更新日期: - 執行後,餘額與最後修改時間更新成功。
範例7-4:將小華的美金轉換成台幣
- 查詢小華的 USD 帳戶。
- 使用
$mul將 cash 欄位乘以匯率28.005,並$settype 為 "TWD"。 - 使用
$currentDate更新最後修改時間。
範例7-5:統一學生學號欄位名稱
若 scores 集合中有的紀錄使用 "studentNumber",有的使用 "studentId",可使用 $rename 運算子將 studentNumber 改為 studentId。
範例7-6、7-7:使用 $max、$min
- $max:若成績低於60分,則改為60分。
- $min:若成績高於100分,則改為100分。
範例7-8:刪除欄位
使用 $unset 移除 accounts 集合中小花帳戶的 currency 欄位。
陣列更新運算子
| 運算子 | 功能說明 |
|---|---|
| $push | 將元素新增至陣列末尾 |
| $push+$position | 將元素新增至陣列指定位置 |
| $pop | 移除陣列的首或尾元素 |
| $pull | 移除陣列中符合條件的元素 |
範例7-9、7-10、7-11、7-12、7-13:
透過 $push、$pop 等運算子可對存放於陣列內的資料進行新增、插入特定位置或移除特定元素。例如:
- 新增一個元素至陣列最後面 ($push)。
- 新增多個元素並指定插入位置 ($push+$position)。
- 移除陣列最後一個元素 ($pop:1)。
- 移除陣列第一個元素 ($pop:-1)。
7.5 MongoDB 批次寫入操作 (Bulk Write)
多次資料操作(如多筆更新、新增、刪除)若一筆一筆執行,會消耗較多時間與資源。透過 Bulk Write 可將多個操作合併在一次請求中執行,降低與資料庫溝通的頻率,提升效率。
Bulk Write 語法:
- operations 可包含 insertOne、updateOne、updateMany、deleteOne、deleteMany、replaceOne。
- writeConcern 設定回應要求。
- ordered 決定批次操作是否依序執行。
範例7-14:批次更新飲料店售出的飲品
假設 drink 集合中有多種飲料品項。我們一次賣出三種飲料,需同時更新各飲料品項的累計銷售金額與售出紀錄。使用 bulkWrite 將三個 updateOne 操作合併成一個請求。
不使用 bulkWrite 則需執行三次 updateOne,有了 bulkWrite 則可僅需一次請求。
7.6 實戰演練:銀行帳戶管理系統
綜合本章所學,我們以 C# 程式語言、Visual Studio 2022 整合開發環境和 MongoDB Driver 製作一個簡單的銀行帳戶管理系統。此系統可執行以下功能:
- 開戶 (insertOne)
- 存款 (updateOne + $inc)
- 提款 (updateMany + $inc)
- 銷戶 ($unset 或 $pull)
- 查詢存款 (find)
流程:
- 安裝 MongoDB Driver 套件
- 建立 AccountsDocument.cs 定義文件結構
- 使用 Builders 類別建立 Filter 與 Update 條件
- 透過 Console 介面讓使用者輸入指令編號,以執行相對應功能
- 每個功能各自實作新增、更新或刪除的邏輯
本範例的程式碼示範如何將 MongoDB 的新增、更新、刪除操作整合到 C# 程式中,同時結合過去章節所學的查詢技巧,使得後端邏輯更為彈性、有效率。
請先 登入 以發表留言。