本篇文章是系列文新手到進階學 MongoDB 的第二篇,要帶大家實際對 MongoDB 進行資料操作~
這篇文章將介紹資料的基本操作,包含:
Create
:創建資料Read
:讀取資料Update
:更新資料Delete
:刪除資料
你也可以在上一篇文章中複習 MongoDB 的基礎概念。
Create 創建資料
在 MongoDB 創建資料的指令很單純,常用的有以下兩個:
insertOne
用於創建一筆新的 document。
下面的例子會在名為products
的 collection 中創建一筆紀錄了商品項目(item)
及商品數量(qty)
的 document:
1 | db.products.insertOne( { item: "card", qty: 15 } ); |
insertMany
用於創建多筆新的 documents。
下面的例子會在名為products
的 collection 中創建三筆 documents。我們將要創建的多筆 documents 放在 Array 中,mongoDB 會依照 array 中 item 的順序去依序 insert:
1 | db.products.insertMany( [ |
還記得 MongoDB 的特性是 Schemaless
的嗎?在創建 document 時,每筆 document 都可以有不同的格式,如上面的stamps
有記錄價錢(price)
這個資訊,前面兩筆則沒有。
ObjectId
如果你透過 MongoDB shell 輸入上方的指令成功創建資料,會看見 MongoDB 回覆了一個 ObjectId
資訊。這個 ObjectId 是什麼呢?
其實我們每創建一筆資料時,MongoDB 都會主動賦予 document 一個獨特的_id
欄位,其值的type(資料格式)
就是我們看到的ObjectId
。我們通常會拿_id
當作該筆資料的主鍵
,因為 MongoDB 可以保證同一個 collection 中每筆 document 的_id
都是獨一無二的。
我們也可以使用自己定義的_id
作為 documet 主鍵。只需要在創建 document 時帶上_id
欄位就行,但我們需要保證自己定義的_id
不會重複,否則創建操作會失敗。
由於標準
JSON
中並沒有定義ObjectId
這個 type,由此可見 document 是以BSON
儲存,而不是常見的JSON
。
Read 讀取資料
MongoDB 中可以透過find
系列指令查詢資料。
find 與 findOne
單純使用find
而不帶參數時,會找到該 collection 中所有資料。
如下面的例子,我們會拿到記錄在 products 這個 collection 裡的所有 product:
1 | db.products.find() // 拿回所有資料 |
一次拿回所有資料雖然方便但效率低落,因此在現實應用中很少這樣做。
我們通常會在find
指令中帶上query(查詢條件)
,用來找出符合我們需求的資料。
下面例子會找出_id = 5
的 document,由於我們知道_id
是獨一無二的,因此可以預期 MongoDB 只會返回一筆(或零筆)資料:
1 | db.products.find( { _id: 5 } ) |
使用
find
會找出所有符合條件的 document。
使用findOne
時,會找出第一筆符合條件的 document。
Operators
MongoDB 提供了許多Operators(操作符)
讓搭配 query 使用,讓我們可以更精準描述想要查詢的資料。
如下面例子中我們使用$gt(greater than)
操作符,幫助我們查詢出所有 distance(距離)> 1000 的航班資訊:
1 | db.flightData.find( { distance: { $gt: 1000 } }) |
另一個例子中我們使用$in
操作符,找出所有 bloodType(血型)是 A 或 B 的 user
1 | db.users.find( { bloodType: { $in: ['A', 'B'] } } ) |
更詳細的 Operator 列表可以參考官方文件。
Cursor Object
當我們透過 shell 操作find
指令時,就算已經加上 query 條件,還是有機會一次拿回過多資料導致效率低落(想像你要搜尋姓氏開頭是 A 的使用者,可能超級超級多)。因為效率考量,使用 shell 的 find 指令時,MongoDB 其實是回傳一個Cursor Object
,而不是所有符合條件的資料。
Cursor Object 包含了:
- 部分資料:MongoDB 預設會回傳 20 筆資料
- 資料指針:指向目前拿到的最後一筆資料。我們可以透過
next
方法向 MongoDB 拿更多資料。
1 | // 透過 find 指令找出所有血型是 A、B 的 user。拿到 mongoDB 回傳的 Cursor object |
關於 Cursor 的更多使用方法可以參考官方文件
Update 更新資料
更新跟創建的方式很像。可以選擇只更新一筆資料、也可以一次更新多筆資料。
updateOne
在操作更新時,我們使用 query 告訴 MongoDB「想要更新哪些資料」以及「如何更新他們」。
如下面的例子,我們在名為inventory
的 collection 中找尋item = paper
的資料,並且把資料的 size 更新為 100:
1 | db.inventory.updateOne( |
由於我們使用
updateOne
指令,就算符合 query 條件的資料有很多筆,MongoDB 也只會更新符合條件的第一筆 document。
updateMany
同上述的例子,如果指令換成updateMany
,則所有符合條件的資料都會被更新。
1 | db.inventory.updateMany( |
使用updateMany
要注意的地方是,如果我們在 query 中沒有放上條件,則 collection 中的所有資料都會被更新,因此要小心使用!
1 | db.inventory.updateMany( |
Delete 刪除資料
deleteOne 與 deleteMany
刪除資料的邏輯跟查詢一樣,我們必須在 query 中描述要被刪除的資料條件。
下述例子會將_id = 5
的 document 刪除:
1 | db.products.deleteOne( { _id: 5 } ) |
相同的,我們可以透過deleteMany
一次刪除多筆資料。
下面例子會將血型為 A 的 user 全部刪除:
1 | db.user.deleteMany( |
要注意的是,如果我們在 query 中沒有放上條件,就會把 collection 裡的所有 documents 全部刪除,因此要謹慎使用!
1 | db.inventory.deleteMany({}) // 清空 inventory Collection |
總結
本篇文章介紹了 MongoDB 中基本的CRUD
指令。
基本上透過這些指令已經能應付大多數的操作。關於每個指令的詳細介紹可以參考官方文件。
下篇文章我們將針對更強大的Aggregate
操作做介紹。
本文章最初刊載在 CoderBridge:7 天新手到進階學 MongoDB系列文中。
評論