上一篇介紹了 MongoDB 中執行 CRUD 操作的其中兩項:新增資料 Insert 及刪除資料 Delete,今天繼續和大家介紹如何在 MongoDB 中 查詢資料 Find 及更新資料 Update。
其實我們在上一篇的範例截圖中就有使用到 mongoDB 的資料查詢指令 find()
,這裡和大家更進一步介紹查詢資料的指令及方法。
指令:findOne(filter, options)
我們可以透過對指定的 field 的 value 進行過濾,例如我們想要在 employee 這個 collection 中查詢 title 是 "Software Architect" 的結果:db.employee.findOne({"title" : "Software Architect"})
要注意的是,透過 findOne()
來查詢只會回傳第一個符合過濾條件的 document,如果想要回傳所有符合條件的 documents,則要使用以下介紹的 find()
。
指令:find(filter, options)
例如我們想要查詢 title 是 "Software Engineer" 的所有資料,可以使用以下查詢指令:db.employee.find({"title": "Software Engineer"})
我們可以發現透過 find()
來查詢,將會回傳所有符合過濾條件的查詢結果。在 employee 這個 collection 中,有三個 document 的 title 是 "Software Engineer"。
除了使用特定 field 的 value 為何來作為過濾條件,在 MongoDB 中我們還可以使用其他的「比較查詢運算子」(Comparison Query Operators)來設定過濾條件,這裡先介紹其中一項 $gt
,也就是「大於」運算子,例如我們想要查詢薪水超過 $6,000 的職員,我們可以使用以下查詢指令:db.employee.find({salary: {$gt: 6000}})
我們也可以使用 count()
來計算查詢結果的 document 數量,例如我們不想知道薪水超過 $6,000 的職員的所有資訊,而只想知道有幾位就好,可以使用以下指令:db.employee.find({salary: {$gt: 6000}}).count()
從回傳結果可以得知,薪水超過 $6,000 的職員有5位。
關於比較查詢運算子這裡先介紹其中一項 $gt
,在之後「進階的 CRUD 操作」的文章會再詳細介紹其他比較查詢運算子,如果有興趣想先了解的朋友,也可以先閱讀官方文檔的介紹。
可以從以上截圖發現本文使用的 collection 中的 document 資料都包含了 "first_name", "last_name", "title", "salary" 及 "hire_date" 等 5 個 fields,我們使用 find()
去查詢資料的回傳結果都會涵蓋符合過濾條件的 document 中的所有 field-value 資料。但很多時候我們沒有想要知道所有 field-value 資料,只想去檢視特定的 field-value 資料,這時候就需要用到 MongoDB 的 映射 Projection觀念,也就是只選擇 document 中的必要資料,而非全部資料。
只回傳 "first_name" 及 "last_name" 這兩個資料:db.employee.find({}, {first_name:1, last_name:1})
只回傳 "first_name" 及 "last_name" 這兩個資料,並且不回傳 "_id":db.employee.find({}, {first_name:1, last_name:1, _id:0})
除了直接新增資料,我們也會想在現有的資料中進行修改更新,我們可以使用 updateOne()
及 updateMany()
來對一個或多個 document 進行資料的修改更新。
指令:updateOne(filter, update, options)
假設我們想要修改 "_id" 為 ObjectId("5f64432bb636c9e897dce2ee") 的 document,將其 salary 從原本 7200 改成 7300,我們可以使用以下指令來修改:db.employee.updateOne({"_id" : ObjectId("5f64432bb636c9e897dce2ee")}, {$set: {"salary": 7300}})
原本:
修改後:
我們可以從上方截圖中更新指令的回傳結果中看到三個回傳資訊:
指令:updateMany(filter, update, options)
我們也可以一次修改所有符合過濾條件的 documents 中的特定資料,例如我們想要將所有 Software Architect 的薪水都調成 $7,333,我們可以使用以下指令來完成:db.employee.updateMany({"title": "Software Architect"}, {$set: {"salary": 7333}})
原本:
修改後:
我們一樣可以從 updateMany()
的回傳結果訊息中得知其執行結果及修改的資料數,也可以透過 find()
去檢視修改的結果。
要注意的是:使用 updateOne()
只會對符合過濾條件的第一個 document 進行修改,若要對所有符合過濾條件的 documents 都進行修改,就要使用 updateMany()
。
要修改多筆資料除了使用 updateMany()
,也可以使用 update()
來執行修改,但兩者還是有許多不同:
update()
不需要使用 $set
update()
只會保留有執行修改更新的部分 -> 危險!!!例如:
update()
將其薪水從 7333 改為 5555:db.employee.update({"_id" : ObjectId("5f64432bb636c9e897dce2ee")}, {"salary": "5555"})
find()
去檢視時發現,document 只剩下我們有修改的 salary 這組 field-value 了
由以上結果可以發現使用 update()
指令來修改資料非常危險,會造成資料消失,因此最好不要使用 update()
來進行資料的修改更新。
除了對特定 field 的 value 值進行修改,也可以直接對符合過濾條件的 document 進行資料覆蓋,例如我們要把上方範例中的資料覆蓋成 {"A": 1, "B": 2},我們可以透過以下指令完成:db.employee.replaceOne({_id : ObjectId("5f64432bb636c9e897dce2ee")}, {"A": 1, "B": 2})
透過 find()
來檢視執行覆蓋後的資料,可以發現原本 "salary" : "5555" 這組 field-value 直接被 "A": 1, "B": 2 所覆蓋了。
這兩天和大家介紹了 MongoDB 的基本 CRUD 操作,下一篇將和大家介紹資料結構較為複雜的 嵌入式文件(embedded document)。