MongoDB 文档的更新操作
在MongoDB中,更新單個(gè)doc的操作是原子性的。默認(rèn)情況下,如果一個(gè)update操作更新多個(gè)doc,那么對(duì)每個(gè)doc的更新是原子性的,但是對(duì)整個(gè)update 操作而言,不是原子性的,可能存在前面的doc更新成功,而后面的doc更新失敗的情況。由于更新單個(gè)doc的操作是原子性的,如果兩個(gè)更新同時(shí)發(fā)生,那么一個(gè)更新操作會(huì)阻塞另外一個(gè),doc的最終結(jié)果值是由時(shí)間靠后的更新操作決定的。
通過使用?$isolated?option,能夠確保更新多個(gè)doc的寫操作是原子性的,任何查詢操作都會(huì)讀取到更新操作,直到該操作完成(成功或失敗)。?
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在新增和更新數(shù)據(jù)的時(shí)候,不會(huì)實(shí)時(shí)寫入到Disk中,可能會(huì)丟失數(shù)據(jù)。
一,語(yǔ)法
默認(rèn)情況下,update只會(huì)更新single doc,如果需要更新多個(gè)doc,必須顯式設(shè)置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中有三個(gè)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選項(xiàng),插入一條新的user,name=“t4”
db.users.update({name:"t4"},{name:"t4"},{upsert:true})對(duì)新插入的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更新多個(gè)doc之前,先考慮一個(gè)問題,如果把a(bǔ)ge的年紀(jì)都加1,那么在age加1時(shí),保持其他field不變。這種情況需要用到$inc operator,用于將指定字段的值遞增,同時(shí)不會(huì)影響其他字段。
{ $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字段,默認(rèn)值是femal。
db.users.update({},{$set:{sex:"femal"}},{multi:true})三,原子更新multiple doc
在query filter中加入 $isolated:1,表示對(duì)于查詢到的所有doc,update操作將會(huì)在一個(gè)原子操作中完成。
db.users.update({$isolated:1},{$set:{sex:"femal"}},{multi:true})四,更新doc的結(jié)構(gòu)
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的數(shù)據(jù)更新
2,使用db.collection.replaceOne替換doc
db.collection.replaceOne(<filter>,<replacement>,{upsert: <boolean>,writeConcern: <document>} )step1,使用findOne()查找一個(gè)doc
t4=db.users.findOne({name:"t4"})step2,為doc增加一個(gè)sex field
t4.sex="femal"step3,使用replaceOne函數(shù)替換doc
db.users.replaceOne({name:"t4"},t4)3,使用$set對(duì)所有符合query filter的doc批量修改doc結(jié)構(gòu)
db.users.update({age:{$lte:23,$gte:21}},{$set:{sex:"femal"}},{multi:true});4,使用$unset對(duì)所有符合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
總結(jié)
以上是生活随笔為你收集整理的MongoDB 文档的更新操作的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 意料之外,也是情理之中 - 我的自由职业
- 下一篇: 14.Java包装类