MongoDB中文档的更新操作

MongoDB 文档更新操作详解

一、更新方法分类

  1. 基础更新方法
    update()
    早期版本的通用更新方法,支持单条/批量更新(需配合multi参数)

    // 更新单条(默认仅更新第一条匹配)
    db.users.update({"name":"laoli"}, {$set:{"age":40}})
    // 批量更新(设置multi:true)
    db.users.update({"age":33}, {$inc:{"score":10}}, {multi:true})
    

    updateOne()
    精确更新单条文档(原子操作),推荐替代update()的旧用法

    db.users.updateOne({"name":"laoli"}, {$set:{"mobile":"18012312312"}})
    

    updateMany()
    批量更新所有匹配文档,性能优于循环updateOne()

    db.users.updateMany({"status":"inactive"}, {$set:{"status":"active"}})
    
  2. 替换操作
    replaceOne()
    完全替换文档内容(保留_id),适用于字段结构重构

    db.books.replaceOne(
      {"_id": ObjectId("59f005402844ff254a1b68f6")},
      {title: "三国演义", author: {name: "罗贯中", age: 99}}
    )
    

二、核心更新运算符

  1. 字段操作符
    $set
    设置/新增字段值,支持嵌套文档操作

    db.users.updateOne({"name":"laoli"}, {$set:{"child.mobile":"18012312312"}})
    

    $unset
    删除字段(包括嵌套字段),布尔值参数仅作占位符

    db.users.update({"name":"laoli"}, {$unset:{"sex":true}})
    

    $rename
    重命名字段(需全路径操作),可能影响索引

    db.users.update({"name":"laoli"}, {$rename:{"lve":"love"}})
    
  2. 数值操作符
    $inc
    数值增减(仅支持整数/浮点数),常用于计数器场景

    db.users.updateMany({"role":"user"}, {$inc:{"login_count":1}})
    
  3. 数组操作符
    $push
    追加数组元素(允许重复),支持$each批量添加

    db.users.update({"name":"laoli"}, {$push:{"hobbies":"coding"}})
    // 批量添加
    db.users.update({"name":"laoli"}, {$push:{"hobbies":{$each:["music","reading"]}}})
    

    $addToSet
    唯一性数组追加,避免重复元素

    db.users.update({"name":"laoli"}, {$addToSet:{"hobbies":"coding"}})
    

    $pull/$pullAll
    删除数组元素(精确匹配/批量删除)

    db.users.update({"name":"laoli"}, {$pull:{"hobbies":"TV"}})
    db.users.update({"name":"laoli"}, {$pullAll:{"hobbies":["game","music"]}})
    

    $pop
    移除首尾元素(1=末尾,-1=开头),类似队列操作

    db.users.update({"name":"laoli"}, {$pop:{"hobbies":1}})
    

三、高级功能与最佳实践

  1. 原子性控制
    • 单文档更新天然原子性,多文档更新需事务支持(v4.0+)
    findAndModify
    查询并原子更新,返回修改前后文档

    db.people.findAndModify({
      query: {name: "Andy"},
      update: {$inc: {score: 1}},
      new: true // 返回更新后的文档
    })
    
  2. 性能优化建议
    索引优化:为高频查询字段创建索引(如db.users.createIndex({name:1})
    批量更新:优先使用updateMany而非循环updateOne(减少网络开销)
    投影控制:结合projection减少返回数据量(仅更新必要字段)

  3. 特殊参数
    upsert
    文档不存在时自动插入(避免先查后插的竞态条件)

    db.inventory.updateOne(
      {item: "paper123"},
      {$set: {stock: 50}},
      {upsert: true}
    )
    

    writeConcern
    设置写操作确认级别(如{w: "majority"}保证集群多数节点写入)


四、注意事项

  1. _id不可修改
    所有更新操作禁止修改_id字段,否则触发ImmutableField错误

  2. 数据类型匹配
    $inc仅适用于数值类型字段(字符串数值需先转换)
    • 字段类型变更可能导致查询异常(如数值→字符串)

  3. 文档大小限制
    更新后文档若超过16MB限制会触发DocumentTooLarge错误,需分片存储或结构调整

建议结合explain("executionStats")分析更新性能,并通过db.collection.getIndexes()验证索引有效性。具体参数细节可参考官方文档

posted @ 2025-03-26 21:53  千陌666  阅读(96)  评论(0)    收藏  举报