iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 5
1
AI & Data

從入門到精通 MongoDB系列 第 5

Day05: MongoDB 的 CRUD(3) - Find & Update

  • 分享至 

  • xImage
  •  

上一篇介紹了 MongoDB 中執行 CRUD 操作的其中兩項:新增資料 Insert 及刪除資料 Delete,今天繼續和大家介紹如何在 MongoDB 中 查詢資料 Find更新資料 Update


查詢資料 Find

其實我們在上一篇的範例截圖中就有使用到 mongoDB 的資料查詢指令 find(),這裡和大家更進一步介紹查詢資料的指令及方法。

findOne()

指令:findOne(filter, options)
我們可以透過對指定的 field 的 value 進行過濾,例如我們想要在 employee 這個 collection 中查詢 title 是 "Software Architect" 的結果:db.employee.findOne({"title" : "Software Architect"})

要注意的是,透過 findOne() 來查詢只會回傳第一個符合過濾條件的 document,如果想要回傳所有符合條件的 documents,則要使用以下介紹的 find()

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 操作」的文章會再詳細介紹其他比較查詢運算子,如果有興趣想先了解的朋友,也可以先閱讀官方文檔的介紹。

映射 Projection

可以從以上截圖發現本文使用的 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})


更新資料 Update

除了直接新增資料,我們也會想在現有的資料中進行修改更新,我們可以使用 updateOne()updateMany() 來對一個或多個 document 進行資料的修改更新。

updateOne()

指令:updateOne(filter, update, options)
假設我們想要修改 "_id" 為 ObjectId("5f64432bb636c9e897dce2ee") 的 document,將其 salary 從原本 7200 改成 7300,我們可以使用以下指令來修改:db.employee.updateOne({"_id" : ObjectId("5f64432bb636c9e897dce2ee")}, {$set: {"salary": 7300}})

  • 原本:

  • 修改後:

我們可以從上方截圖中更新指令的回傳結果中看到三個回傳資訊:

  • acknowledged:執行結果是否成功
  • matchedCount:符合過濾條件的 document 數
  • modifiedCount:成功修改資料的 document 數

updateMany()

指令:updateMany(filter, update, options)
我們也可以一次修改所有符合過濾條件的 documents 中的特定資料,例如我們想要將所有 Software Architect 的薪水都調成 $7,333,我們可以使用以下指令來完成:db.employee.updateMany({"title": "Software Architect"}, {$set: {"salary": 7333}})

  • 原本:

  • 修改後:

我們一樣可以從 updateMany() 的回傳結果訊息中得知其執行結果及修改的資料數,也可以透過 find() 去檢視修改的結果。

要注意的是:使用 updateOne() 只會對符合過濾條件的第一個 document 進行修改,若要對所有符合過濾條件的 documents 都進行修改,就要使用 updateMany()

update() 和 updateMany() 的比較

要修改多筆資料除了使用 updateMany(),也可以使用 update() 來執行修改,但兩者還是有許多不同:

  • update() 不需要使用 $set
  • update() 只會保留有執行修改更新的部分 -> 危險!!!

例如:

  • 原本的資料為
  • 使用 update() 將其薪水從 7333 改為 5555:db.employee.update({"_id" : ObjectId("5f64432bb636c9e897dce2ee")}, {"salary": "5555"})
  • 透過 find() 去檢視時發現,document 只剩下我們有修改的 salary 這組 field-value 了

由以上結果可以發現使用 update() 指令來修改資料非常危險,會造成資料消失,因此最好不要使用 update() 來進行資料的修改更新。

replaceOne()

除了對特定 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)


上一篇
Day04: MongoDB 的 CRUD(2) - Insert & Delete
下一篇
Day06: MongoDB 的 CRUD(4) - Document 及對複雜 document 進行過濾
系列文
從入門到精通 MongoDB26
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言