Day 2 - MongoDB 的 CRUD


前言

上一篇文章中,我們介紹了 MongoDB 的基礎概念。
本篇文章開始,要帶大家實際對 MongoDB 進行資料操作!

這篇文章將介紹資料的基本 CRUD 操作:

  • Create 創建資料
  • Read 讀取資料
  • Update 更新資料
  • Delete 刪除資料

Create 創建資料

在 MongoDB 創建資料的指令很單純,常用的有以下兩個:

insertOne

用於創建一筆新的 Document。

下面的例子會在名為 products 的 Collection 中創建一筆包含 商品項目(item)商品數量(qty) 的 Document:

db.products.insertOne( { item: "card", qty: 15 } );

insertMany

用於一次創建 多筆 新的 Document。

我們將要創建的多筆 Document 放在 Array 中,下面的例子會在名為 products 的 Collection 中一次創建三筆 Document:

db.products.insertMany( [
      { item: "card", qty: 15 },
      { item: "envelope", qty: 20 },
      { item: "stamps" , qty: 30, price: 1000 } // 有 price 資訊的 document
   ] );

還記得 MongoDB 的特性是 Schemaless 的嗎?在創建 Document 時,每筆 Document 都可以有不同的格式,如上面的 stamps 有記錄 price 價錢 這個資訊,而前面兩筆 Document 則沒有。

ObjectId

如果你透過 MongoDB shell 輸入上方的指令成功創建資料,會看見 MongoDB 回覆了一個 ObjectId 資訊。這個 ObjectId 是什麼呢?

原來,每當我們創建一筆資料,MongoDB 都會主動在 Document 中賦予一個獨特的 _id 欄位,其值的 資料格式 type 就是我們看到的 ObjectId()
_id 欄位可以當作該 Document 的 主鍵,因為 MongoDB 可以保證同一個 Collection 中每筆 Document 的 _id 都是 獨一無二不重複 的。

由於標準 JSON 中並沒有定義 ObjectId 這個資料格式 ,由此可見 MongoDB 中的 Document 是以 BSON 儲存,而不是常見的 JSON

我們可以使用自己定義的 _id 作為 Documet 的主鍵。只需要在創建 Document 時帶上 _id 欄位就行,但我們需要保證自己定義的 _id 不會重複,否則創建操作會失敗。

Read 讀取資料

MongoDB 中可以透過 find 指令查詢資料。

find

單純使用 find 指令時,會找到該 Collection 中的所有資料
如下面的例子,我們會拿到 products 這個 Collection 中的所有資料:

db.products.find() // 拿回所有資料

然而一次拿回所有資料,在資料量變多時非常沒有效率。我們可以在 find 指令中帶上查詢資料的 條件 query,用來找出所有符合我們條件的資料。

下面例子會找出 _id 為 5 的 document,由於我們知道 _id 是獨一無二不重複的,因此可以預期 MongoDB 只會返回一筆(或零筆)資料:

db.products.find( { _id: 5 } )

使用 find 時會找出所有符合條件的 document。
使用 findOne 時,會找出第一筆符合條件的 document。

Operators

MongoDB 針對 query 條件提供了許多 操作符 Operators,讓我們可以更精準描述想要查詢的資料。

如下面例子中我們使用 $gt 這個操作符,幫助我們查詢出所有 distance 距離 大於 1000 的航班資訊:

db.flightData.find( { distance: { $gt: 1000 } })

另一個例子中我們使用 $in 操作符,來找出所有 bloodType 血型A 或 B 的 user

db.users.find( { bloodType: { $in: ['A', 'B'] } } )

MongoDB 提供了豐富的 Query Operator 幫助我們 精準 的描述出欲查詢的資料長相。更詳細的 Operator 列表可以參考官方文件

Update 更新資料

更新跟創建的方式很像。可以選擇只更新一筆資料、也可以一次更新多筆資料。

updateOne

在操作更新時,我們需要描述 query(要被更新資料的條件),以及 要更新的欄位
如下面的例子,我們在 inventory Collection 中找尋 item 是 paper 的 Document,並且更新該資料的 size 為 100:

db.inventory.updateOne(
   { item: "paper" },
   {
     $set: { "size": 100 },
   }
)

由於我們使用 updateOne 指令,就算符合 query 條件的 Document 有多筆,MongoDB 也只會更新 符合條件的第一筆 Document

updateMany

同上述的例子,如果指令換成 updateMany,則所有符合 query 條件 的資料都會被更新。

db.inventory.updateMany(
   { item: "paper" }, // 所有 item 欄位值是 paper 的資料都會被更新
   {
     $set: { "size": 100 },
   }
)

使用 updateMany 要注意的地方是,如果我們在 query 中並沒有指令條件,則 Collection 中的所有資料都會被更新:

db.inventory.updateMany(
    {}, // 由於 query 為空,所有 document 都會加上 message 這個欄位
    {
        $set: { message: 'Opps' }
    }
)

Delete 刪除資料

deleteOnedeleteMany

刪除資料的邏輯跟查詢一樣,我們必須在 query 中描述要被刪除的資料條件。

下述例子會將 _id 是 5 的 document 刪除:

db.products.deleteOne( { _id: 5 } )

相同的,我們可以透過 deleteMany 一次刪除多筆資料。下面例子會將所有 血型為 A 的 user 都刪除:

db.user.deleteMany(
   { bloodType: "A" }, // 所有血型為 A 的 user 都被刪除
)

要注意的是,如果 query 為空,就會將該 Collection 中的所有 Document 全部刪除,因此要謹慎使用!

db.inventory.deleteMany({}) // 清空 inventory Collection

總結

本篇文章我們介紹了 MongoDB 中基本的 CRUD 指令。
基本上透過 CRUD 指令已經可以應付大多數的操作。關於每個指令的詳細介紹可以參考 官方文件

下篇文章我們將針對更強大的 Aggregate 操作做介紹。

BitWise 分享

除了參與本次 寫作松 分享軟體開發的技術之外,
我在 Podcast 節目 【 BitWise 一點智慧 】 中也會以輕鬆的角度,跟大家聊聊軟體開發、設計、學習!歡迎大家收聽~~

👉 用Apple收聽
👉 用Spotify收聽
👉 用Google收聽
👉 官方網站

#mongoDB #Backend #Database
用七天的時間從新手變成高手!包含 MongoDB NoSQL 的特性、基本 CRUD 操作、複雜卻高效的 Aggregate 操作、提升查詢效能的 Index 建置等議題。






Related Posts

一起探討 Micro Frontends 的世界

一起探討 Micro Frontends 的世界

[13] 值 - 字串

[13] 值 - 字串

Day06_Origami學習筆記

Day06_Origami學習筆記

淺談 CSS 方法論與 Atomic CSS

淺談 CSS 方法論與 Atomic CSS

了解 WebAssembly 的基礎使用方法

了解 WebAssembly 的基礎使用方法

容器化的概念

容器化的概念



Comments