https://flic.kr/p/qakxAH
MongoDB 是一款 NoSQL 資料庫。它與關聯式資料庫最大的不同,是以類似 JSON 格式的方式來儲存資料。使用上也沒有嚴格的 schema 跟 constraint,因此在欄位設計與資料儲存上能夠更有彈性。本文將會建立 MongoDB 資料庫,並示範最基本的 CRUD(新增、查詢、修改與刪除)語法。
一、安裝 MongoDB 與使用圖形化介面工具
關於安裝資料庫的方式,可參考筆者這篇文章的第一節,並留意開啟與關閉 Windows 服務的方式。在安裝過程中,會遇到一個步驟是詢問是否要安裝工具「MongoDB Compass」。此處不需要安裝,因為在這系列文章,筆者會使用另一個圖形化介面工具(GUI Tool),叫做「NoSQLBooster」。
請讀者另外下載安裝 NoSQL Booster。開啟後,點擊左上方的「Connect」按鈕,會出現管理資料庫連線設定的視窗。若讀者想存取不同台伺服器上的資料庫,就能在這裡建立多個需要的連線(connection)。
按下「Create」按鈕,可以填寫連線設定並建立一個連線。在下圖中,「Server」欄位填寫的是資料庫的位址與埠號。而「Name」欄位是命名我們要在 GUI 看的名稱。若讀者想連線的資料庫有帳密保護,請到「Authentication」頁籤做其他設定。最後按下「Save」按鈕即可儲存,再按下「Connect」就能連線到資料庫。
連線到資料庫後,讓我們開始在上面建立資料庫。在 NoSQLBooster 畫面的左上方,有個「Open Connection」區塊。請在要操作的連線上按右鍵,選擇「Create Database」,輸入資料庫名稱後按下 OK。此例筆者輸入的名稱是「StudentGrade」,是一個儲存學生成績的資料庫。
接著在資料庫上按右鍵,選擇「Create Collection」。在 MongoDB,這裡的 collection(集合)如同關聯式資料庫的 table;而 document(文件)指的則是存放的資料。此例的 collection 名稱為「student」,用來存放學生的 document。
二、新增資料
建立好資料庫和 collection 後,就能開始學習語法了。在左邊的 Open Connection 區塊,對想要操作的連線按右鍵,選擇「Run SQL Query」,可在右邊開啟撰寫語法的視窗。MongoDB 的語法有點像 JavaScript。我們可以用「物件.方法」的模式來撰寫,並用大括號 { } 來宣告物件,用中括號 [ ] 來宣告陣列,再傳入方法中。
這一節會從新增資料的語法開始。首先寫出 db.student,代表要對資料庫的 student 集合進行操作。接著寫下 .insertOne(),呼叫新增一筆資料的方法,我們對該方法傳入一個物件參數。
db.student.insertOne( { "studentId": "10346000", "name": "Vincent", "majority": ["資訊管理", "財務金融"] } )
隨後即可按下上方的「Run」按鈕執行,如下圖。
在下方的 console 視窗能看到回傳結果。其中 insertedId 的值是一個「ObjectId」,它是 MongoDB 為 document 自動產生的 id。
若讀者想要一次新增多筆資料,可以使用 insertMany 方法,傳入 document 的陣列。
db.student.insertMany( [ { "studentId": "10342000", "name": "Dora", "majority": ["財務金融"] }, { "studentId": "10345000", "name": "Winnie", "majority": ["企業管理"] } ] )
而回傳結果同樣包含已新增文件的 ObjectId。
另外還有一個比較舊版,且已被 deprecated 的 insert 方法,它的參數同時接受物件與陣列。與上述兩者的差別在於回傳的結果,insert 方法只會回傳新增的資料筆數。
三、查詢資料
新增完資料後,讓我們看看儲存的狀況。使用 find 方法可以進行查詢,它接受一個物件參數,代表查詢條件。若沒有條件,則傳入「空物件」就好,以取得 collection 中的所有資料。
db.student.find( {} )
下圖為查詢結果。檢視方式是 Tree,讀者亦可在右上方切換成其他的,如 JSON、Table。
接下來使用單一欄位來查詢。此處查詢 name 欄位為「Vincent」的學生。做法是在查詢條件的物件中添加屬性,key 為欄位名稱,value 為目標的值。
db.student.find( { "name": "Vincent" } )
再來是針對陣列欄位來查詢。此處查詢 majority 欄位為「財務金融」的學生。比較特別的是,只要陣列元素包含這個值,就算符合條件。以此例來說,會找出兩個 document。
db.student.find( { "majority": "財務金融" } )
最後示範用 document 的 id 來查詢。要注意的是「_id」的值需給予 ObjectId。
db.student.find( { "_id": ObjectId("61f8dfcbaa42a213609a6990") } )
本文只介紹簡單的查詢。更多查詢方式,請參考官方文件或筆者的下一篇【MongoDB】如何撰寫查詢語法。
四、刪除資料
本節來學習刪除資料的語法。其實與查詢資料類似,都需要傳入查詢條件。我們假設 student 這個 collection 中有以下資料。
(一)deleteOne 方法
使用 deleteOne 方法可刪除查詢到的第一筆資料。以下的語法是刪除 _id 欄位為給定 ObjectId 的一筆資料。
db.student.deleteOne( { "_id": ObjectId("61fb84671d8a0e494354075d") } )
該方法會回傳一個物件,內含已刪除的資料筆數。
{ "acknowledged": true, "deletedCount": 1 }
(二)deleteMany 方法
使用 deleteMany 方法可刪除查詢到的所有資料。以下的語法是刪除 grade 欄位的值為 4 的所有資料。該方法也會回傳與 deleteOne 方法相同的物件,以此例來說,deletedCount 的值為 2。
db.student.deleteMany( { "grade": 4 } )
(三)findOneAndDelete 方法
使用 findOneAndDelete 方法可刪除查詢到的第一筆資料,並回傳該筆資料。若未查詢到資料,則回傳 null。以下的語法是刪除 majority 欄位為「財務金融」的資料。
db.student.findOneAndDelete( { "majority": "財務金融" } )
以此例來說,雖然有兩筆資料符合條件,但仍只會刪除並回傳第一筆資料。以下是在 console 視窗印出的內容。
{ _id: new ObjectId("61fb84671d8a0e4943540759"), name: 'Vincent', majority: [ '資訊管理', '財務金融' ], grade: 3 }
若再執行一次,才會刪除下一筆。
五、更新資料
本節來學習更新資料的語法,更新與刪除都需要傳入查詢條件。不過讀者可以對欄位指定各式各樣的更新方式。本節我們同樣假設 student 這個 collection,其初始資料與上一節相同。
使用 save 方法,並傳入一個物件,可以覆蓋具有相同 _id 欄位值的 document。適合用於事先將資料查詢出來,單純用程式碼進行修改內容,再存回 collection 的場景。有點像在用 JavaScript 寫預存程序(Stored Procedure)。
以下的範例是查出 collection 中所有資料,將 majority 陣列欄位的每個元素加上「系」字,再儲存。
// 查詢資料 const students = db.student.find({}).toArray() students.forEach(stu => { // 修改資料 const majority = stu.majority.map(m => m += "系") stu.majority = majority // 儲存 db.student.save(stu) })
使用 updateMany 方法,除了傳入查詢條件,讀者還可搭配各種操作符號來實現想要的更新方式。
(一)$set 操作符號
使用 $set 符號可以更新欄位的值。若欄位不存在,則視為新增欄位並給予該值。以下的範例是查出 name 欄位值為「Vincent」的資料,修改其 name 欄位值,並新增 birthday 欄位。
db.student.updateMany( { "name": "Vincent" }, { "$set": { "name": "Vincent Zheng", "birthday": ISODate("1996-01-01") } } )
(二)$unset 操作符號
使用 $unset 符號可以移除指定欄位。以下的範例是移除所有 document 的 birthday 欄位。
db.student.updateMany( {}, { "$unset": { "birthday": "" } } )
關於 birthday 的值給予空字串,MongoDB 的文件提到給予的值不會影響操作。所以隨意給個值即可。
(三)$inc 操作符號
使用 $inc 符號,可以將數值欄位的值增加我們給予的值,也能提供負數或小數點。以下的範例是將所有 document 的 grade 欄位值增加 1。
db.student.updateMany( {}, { "$inc": { "grade": 1 } } )
本文只簡單地介紹幾個操作符號。更多操作方式,請參考官方文件或筆者的【MongoDB】使用操作符號來更新資料文章。
留言
張貼留言