MongoDB 文档的更新操作
在MongoDB中,更新單個doc的操作是原子性的。默認情況下,如果一個update操作更新多個doc,那么對每個doc的更新是原子性的,但是對整個update 操作而言,不是原子性的,可能存在前面的doc更新成功,而后面的doc更新失敗的情況。由于更新單個doc的操作是原子性的,如果兩個更新同時發生,那么一個更新操作會阻塞另外一個,doc的最終結果值是由時間靠后的更新操作決定的。
通過使用?$isolated?option,能夠確保更新多個doc的寫操作是原子性的,任何查詢操作都會讀取到更新操作,直到該操作完成(成功或失敗)。?
Prevents a write operation that affects multiple documents from yielding to other reads or writes once the first document is written. By using the?$isolatedoption, you can ensure that no client sees the changes until the operation completes or errors out.
MongoDB在新增和更新數據的時候,不會實時寫入到Disk中,可能會丟失數據。
一,語法
默認情況下,update只會更新single doc,如果需要更新多個doc,必須顯式設置doc: multi:true。
db.collection.update(<query>,<update>,{upsert: <boolean>,multi: <boolean>,writeConcern: <document>} )upsert:Optional. If set to?true, creates a new document when no document matches the query criteria. The default value is?false, which does not insert a new document when no match is found.
multi:Optional. If set to?true, updates multiple documents that meet the?query?criteria. If set to?false, updates one document. The default value is?false.
二,更新示例
在users collection中有三個doc,插入代碼如下
user1={ name:"t1", age:21} user2={ name:"t2", age:22} user3={ name:"t3", age:23}db.users.insert([user1,user2,user3])1,upsert option usage
upsert option的含義是,如果collection中存在匹配的doc,那么更新該doc;如果不匹配任何doc,那么插入一條新的doc。
使用update命令和 upsert選項,插入一條新的user,name=“t4”
db.users.update({name:"t4"},{name:"t4"},{upsert:true})對新插入的user新增field:age=24,必須將doc的所有field都顯式指定。
db.users.update({age:24},{name:"t4",age:24})如果在Update doc中,只包含age=24,那么將失去name field,例如
db.users.update({name:"t4"},{age:24})2,multi option usage
在使用multi option更新多個doc之前,先考慮一個問題,如果把age的年紀都加1,那么在age加1時,保持其他field不變。這種情況需要用到$inc operator,用于將指定字段的值遞增,同時不會影響其他字段。
{ $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }示例,將符合條件的User的age 加 1
db.users.update({age:{$lt:24}},{$inc:{age:1}},{multi:true})3,為所有的user 增加字段
這種scenario需要用到$set operator,用于替換指定字段的值,或新增字段。
{ $set: { <field1>: <value1>, ... } }The?$set?operator replaces the value of a field with the specified value. If the field does not exist,?$set?will add a new field with the specified value, provided that the new field does not violate a type constraint. If you specify a dotted path for a non-existent field,?$set?will create the embedded documents?as needed?to fulfill the dotted path to the field.
示例,為所有的user增加sex字段,默認值是femal。
db.users.update({},{$set:{sex:"femal"}},{multi:true})三,原子更新multiple doc
在query filter中加入 $isolated:1,表示對于查詢到的所有doc,update操作將會在一個原子操作中完成。
db.users.update({$isolated:1},{$set:{sex:"femal"}},{multi:true})四,更新doc的結構
1,將doc的sex field刪除
Step1,使用FindOne找到name=t4的User
t4=db.users.findOne({name:"t4"})Step2,使用delete command 刪除sex field
delete t4.sex;Step3,使用Updae 替換原來的doc
db.users.update({name:"t4"},t4);step4,使用find 查看doc的數據更新
2,使用db.collection.replaceOne替換doc
db.collection.replaceOne(<filter>,<replacement>,{upsert: <boolean>,writeConcern: <document>} )step1,使用findOne()查找一個doc
t4=db.users.findOne({name:"t4"})step2,為doc增加一個sex field
t4.sex="femal"step3,使用replaceOne函數替換doc
db.users.replaceOne({name:"t4"},t4)3,使用$set對所有符合query filter的doc批量修改doc結構
db.users.update({age:{$lte:23,$gte:21}},{$set:{sex:"femal"}},{multi:true});4,使用$unset對所有符合query filter的doc批量刪除doc的field
db.users.update({$and:[{age:{$lte:23}},{age:{$gte:21}}]},{$unset:{sex:"femal"}},{multi:true})--or db.users.update({age:{$lte:23,$gte:21}},{$set:{sex:"femal"}},{multi:true});?
?
參考doc:
Update Documents
Atomicity and Transactions
$isolated
$set
總結
以上是生活随笔為你收集整理的MongoDB 文档的更新操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 意料之外,也是情理之中 - 我的自由职业
- 下一篇: crm使用soap创建下拉框