• 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

  • 相关阅读:
    vue 高度 动态更新计算 calcHeight watch $route
    vue 自定义组件 v-model双向绑定、 父子组件同步通信【转】
    vue 异步请求数据后,用v-if,显示组件,这样初始化的值就在开始的时候传进去了
    vue $parent 的上一级 有可能不是父组件,需要好几层$parent 如果这样 还不如用 this.$emit
    vue render {} 对象 说明文档
    params.row[params.column.key] vue h函数 当前单元格 h函数 div 属性 值或数组 render
    upload 上传按钮组件 iview
    下拉列表事件 Dropdown iview
    this.treeData = JSON.parse(JSON.stringify(this.d)) 树的序列化反序列化
    tree iview treeData json数据 添加 selected 数据 要进行vue.set 进行响应式添加
  • 原文地址:https://www.cnblogs.com/zxtceq/p/7690958.html
Copyright © 2020-2023  润新知