MongoDB更新文件
本文命令都是在mongo shell下實戰的,到了真實的web專案中這些命令對應的實現都是有封裝的,所以不用被嚇到
先貼上官方正統文件 英文文件 ,下面的連結都是中文社群的 :joy:
MongoDB更新文件的方法很多,尤其是在3.2以後,主要的方法有以下幾種.
db.collection.updateOne() 即使可能有多個文件通過過濾條件匹配到,但是也最多也只更新一個文件。3.2 新版功能.
db.collection.updateMany() 更新所有通過過濾條件匹配到的文件.3.2 新版功能.
db.collection.replaceOne() 即使可能有多個文件通過過濾條件匹配到,但是也最多也只替換一個文件。3.2 新版功能.
db.collection.update() 即使可能有多個文件通過過濾條件匹配到,但是也最多也只更新或者替換一個文件。預設情況下只更新一個 文件。要更新多個文件,請使用 multi 選項
db.collection.save() 通過傳入的文件來替換已有文件。
本文只對update()方法做說明,其餘幾個放發內建了連結可以去看官方文件
update()語法
db.collection.update( <filter>, <update>, { upsert: <boolean>, writeConcern: <document>, collation: <document> } )
引數說明:
- query : update的查詢條件,類似sql update查詢內where條件。
-
update
: update的物件和一些更新的操作符(如
$set
,$inc
...)等,也可以理解為sql update查詢內set後面的 - upsert : 可選,這個引數的意思是,如果不存在update的記錄,是否插入一條新的文件,true為插入,預設是false,不插入。
- multi : 可選,mongodb 預設是false,只更新找到的第一條記錄,如果這個引數為true,就把按條件查出來多條記錄全部更新。
- writeConcern :可選,丟擲異常的級別。
update過濾文件語法
1.相等查詢
{ <field1>: <value1>, <field2>: <value2>...}
表示式指定相等
條件,查詢滿足<field>
等於<value>
的所有文件,可以指定多組條件
2.查詢操作符來指定查詢條件
{ <field1>: { <operator1>: <value1> }, ... }
指定操作符查詢條件需要巢狀{},如查詢age欄位大於20的
{"age" : {$gt: 20}}
我們接著上一篇文章來測試,首先檢視users文件的記錄
> db.users.find().pretty() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 22, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 42, "gender" : "male" } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 23, "gender" : "female" }
pretty()方法可以在終端美化輸出結果
我們將tom的age改為20
> db.users.update({"name" : "tom"}, {$set : {"age" : 20}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 20, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 42, "gender" : "male" } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 23, "gender" : "female" }
這裡就不用pretty()方法美化了,篇幅太長:joy:
看第二條文件,tom的年齡被改為了20
將Jack和Lucy的年齡改為25該怎麼做呢,先來個錯誤命令
> db.users.update({"name" : {$in : ["Jack", "Lucy"]}}, {$set: {"age" : 25}}) WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }) > db.users.find() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 20, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 25, "gender" : "male" } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 23, "gender" : "female" }
問題:只有Jack的年齡被更新為25而Lucy的沒有,前面說了update()
只更新匹配到的第一條記錄,要想更新多條需要設定multi
引數。來看下一條命令
> db.users.update({"name" : {$in : ["Jack", "Lucy"]}}, {$set: {"age" : 28}}, {multi : true}) WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 }) > db.users.find() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 20, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 28, "gender" : "male" } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 28, "gender" : "female" }
這裡加了{multi: true}
引數,所以Jack和Lucy的age都被設定成了28。如果更新的文件不存在呢?我們嘗試一下將upsert
設定為true,來看下一條命令
> db.users.update({"name":"Lucys"}, {$set : {"is_active": 0}}, {upsert: true}) WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : ObjectId("5c77946b96c95d22dfe8b411") }) > db.users.find() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 20, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 28, "gender" : "male" } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 28, "gender" : "female" } { "_id" : ObjectId("5c77946b96c95d22dfe8b411"), "name" : "Lucys", "is_active" : 0 }
可以看到這裡mongodb新增了一條文件,而且除了_id
欄位外,其餘的欄位都出現在了更新語句中,沒出現的在文件中沒有.對於upsert
和multi
引數你也可以這麼設定
> db.users.update({"age": {$gt: 25}}, {$set: {"is_active": 1}}, false, true) WriteResult({ "nMatched" : 3, "nUpserted" : 0, "nModified" : 3 }) > db.users.find() { "_id" : ObjectId("5c77461437955b945af7321f"), "name" : "緣來是你", "age" : 27, "gender" : "male", "is_active" : 1 } { "_id" : ObjectId("5c77499137955b945af73220"), "name" : "tom", "age" : 20, "gender" : "male" } { "_id" : ObjectId("5c77499137955b945af73221"), "name" : "Linda", "age" : 18, "gender" : "female" } { "_id" : ObjectId("5c77731d37955b945af73222"), "name" : "Hanmeimei", "age" : 17, "gender" : "female" } { "_id" : ObjectId("5c7774b736397a1c0aa425ea"), "name" : "Jack", "age" : 28, "gender" : "male", "is_active" : 1 } { "_id" : ObjectId("5c7774b736397a1c0aa425eb"), "name" : "Lucy", "age" : 28, "gender" : "female", "is_active" : 1 } { "_id" : ObjectId("5c77946b96c95d22dfe8b411"), "name" : "Lucys", "is_active" : 0 }
第一個引數false
是upsert
的值,第二個true
是multi
的值