在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 $isolated option, 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。

  1. db.collection.update(
  2. <query>,
  3. <update>,
  4. {
  5. upsert: <boolean>,
  6. multi: <boolean>,
  7. writeConcern: <document>
  8. }
  9. )

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,插入代码如下

  1. user1={ name:"t1", age:21}
  2. user2={ name:"t2", age:22}
  3. user3={ name:"t3", age:23}
  4.  
  5. db.users.insert([user1,user2,user3])

1,upsert option usage

upsert option的含义是,如果collection中存在匹配的doc,那么更新该doc;如果不匹配任何doc,那么插入一条新的doc。

使用update命令和 upsert选项,插入一条新的user,name=“t4”

  1. db.users.update({name:"t4"},{name:"t4"},{upsert:true})

对新插入的user新增field:age=24,必须将doc的所有field都显式指定。

  1. db.users.update({age:24},{name:"t4",age:24})

如果在Update doc中,只包含age=24,那么将失去name field,例如

  1. db.users.update({name:"t4"},{age:24})

2,multi option usage

在使用multi option更新多个doc之前,先考虑一个问题,如果把age的年纪都加1,那么在age加1时,保持其他field不变。这种情况需要用到$inc operator,用于将指定字段的值递增,同时不会影响其他字段。

  1. { $inc: { <field1>: <amount1>, <field2>: <amount2>, ... } }

示例,将符合条件的User的age 加 1

  1. db.users.update({age:{$lt:24}},{$inc:{age:1}},{multi:true})

3,为所有的user 增加字段

这种scenario需要用到$set operator,用于替换指定字段的值,或新增字段。

  1. { $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。

  1. db.users.update({},{$set:{sex:"femal"}},{multi:true})

三,原子更新multiple doc

在query filter中加入 $isolated:1,表示对于查询到的所有doc,update操作将会在一个原子操作中完成。

  1. db.users.update({$isolated:1},{$set:{sex:"femal"}},{multi:true})

四,更新doc的结构

1,将doc的sex field删除

Step1,使用FindOne找到name=t4的User

  1. t4=db.users.findOne({name:"t4"})

Step2,使用delete command 删除sex field

  1. delete t4.sex;

Step3,使用Updae 替换原来的doc

  1. db.users.update({name:"t4"},t4);

step4,使用find 查看doc的数据更新

2,使用db.collection.replaceOne替换doc

  1. db.collection.replaceOne(
  2. <filter>,
  3. <replacement>,
  4. {
  5. upsert: <boolean>,
  6. writeConcern: <document>
  7. }
  8. )

step1,使用findOne()查找一个doc

  1. t4=db.users.findOne({name:"t4"})

step2,为doc增加一个sex field

  1. t4.sex="femal"

step3,使用replaceOne函数替换doc

  1. db.users.replaceOne({name:"t4"},t4)

3,使用$set对所有符合query filter的doc批量修改doc结构

  1. db.users.update({age:{$lte:23,$gte:21}},{$set:{sex:"femal"}},{multi:true});

4,使用$unset对所有符合query filter的doc批量删除doc的field

  1. db.users.update({$and:[{age:{$lte:23}},{age:{$gte:21}}]},{$unset:{sex:"femal"}},{multi:true})
  2.  
  3. --or
  4. db.users.update({age:{$lte:23,$gte:21}},{$set:{sex:"femal"}},{multi:true});

参考doc:

Update Documents

Atomicity and Transactions

$isolated

$set

MongoDB 文档的更新操作的更多相关文章

  1. 【三】MongoDB文档的CURD操作

    一.插入文档 使用insert方法插入文档到一个集合中,如果集合不存在创建集合,有以下几种方法: db.collection.insertOne({}):(v3.2 new)  #插入一个文档到集合中 ...

  2. es之对文档进行更新操作

    5.7.1:更新整个文档 ES中并不存在所谓的更新操作,而是用新文档替换旧文档: 在内部,Elasticsearch已经标记旧文档为删除并添加了一个完整的新文档并建立索引.旧版本文档不会立即消失 ,但 ...

  3. MongoDB 文档的删除操作

    在db中删除数据是十分危险的事,建议使用logic delete,即在doc中增加一个field:IsDeleted,将其设置为1,表示该doc在逻辑上被删除,这种workaround将delete操 ...

  4. mongoDB文档操作

    数据库操作无非就是增.删.改.查.这篇主要介绍增.删.改. 1.增 Mongodb插入操作很简单,使用关键字“insert”.实例: > db.test.blog.insert({"h ...

  5. MongoDB文档的增删改操作

    上一篇文章中介绍了MongoDB的一些基本知识,同时看到了怎么启动一个MongoDB服务,并且通过MongoDB自带的shell工具连接到了服务器. 这一次,就通过MongoDB shell介绍一下对 ...

  6. mongoDB 文档操作_删

    mongoDB 文档删除 MySQL对比 mysql delete from table where ... mongo db.collection.deleteOne(query) 删除函数 del ...

  7. MongoDB文档基本操作

    一.插入文档 使用insert()或save()方法向集合插入文档 >db.COLLECTION_NAME.insert(document) 详细用法可以参考MongoDB菜鸟教程 二.查找文档 ...

  8. MongoDB文档的基本操作

    1. MongoDB的安装方法 (1)下载MongoDB 相应的版本: (2)设置数据文件和日志文件的存放目录: (3)启动MongoDB服务: (4)将MongoDB作为服务启动. 2. Mongo ...

  9. mongodb文档的CRUD

    本章会介绍对数据库移入或者移出数据的基本操作 向集合添加文档 从集合删除文档 更新现有的文档 为这些操作选择合适的安全级别 添加删除数据库 添加数据库 :use foo  如果存在foo 就use   ...

随机推荐

  1. BZOJ 2342 & manachar+最优性剪枝

    题意: 求最长回文串,串的两边都是回文串. Solution: manachar预处理然后暴力找... Code: #include <iostream> #include <cst ...

  2. Hadoop各商业发行版之比较

    Hadoop的发行版除了社区的Apache hadoop外,cloudera,hortonworks,mapR,EMC,IBM,INTEL,华为等等都提供了自己的商业版本.商业版主要是提供了专业的技术 ...

  3. JS 将数字转化成为货币格式

    最近由于项目的需要需要将数字format成货币格式,自己搞了半天效果不是很好,博客园有篇问题很好,再次转载记录一下 http://www.cnblogs.com/mingmingruyuedlut/a ...

  4. Mybatis添加到Spring

    一.准备工作: 1.1 添加相应的jar包依赖: 这里用到了两个jar包,一个是mybatis的,另一个是mybatis-spring的,代码如下: 1 2 3 4 5 6 7 8 9 10 < ...

  5. javascript模块化编程(三):require.js用法

    本文来自阮一峰 这个系列的第一部分和第二部分,介绍了Javascript模块原型和理论概念,今天介绍如何将它们用于实战. 我采用的是一个非常流行的库require.js. 一.为什么要用require ...

  6. Mac下搭建hexo

    Mac下搭建hexo 并部署到gitcafe 1.安装brewhome ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homeb ...

  7. bat 延时删除指定文件夹中的文件经验分享

    1.bat延时 xp程序中通过ping 127.0.0.1 -n 20 来实现延时操作,ping本地地址20行. win7中通过timeout 20 来实现延时20秒. 2.删除指定文件 del /q ...

  8. gem安装报错解决方法

    gem install  rdiscount -- --use-system-libraries

  9. c#控制打印机杂项

    因项目中需要用到控制打印机的相关信息,此贴将网络寻找的资料做了些整理 1. C# 如何设置系统的默认打印机 using System.Runtime.InteropServices;   [DllIm ...

  10. 游戏编程技巧 - Type Object

    Type Object 使用场景 你在制作一款和LOL类似的游戏,里面有许多英雄,因此你想建立一个英雄基类,然后把各种英雄都继承自该基类,这些英雄类都有生命值和攻击力等属性.每次策划想增加一个英雄,你 ...