Skip to content

MongoDB 更新文档

MongoDB 提供了多种更新文档的方法,可以更新单个或多个文档。

更新单个文档

updateOne() 方法

javascript
db.collection.updateOne(filter, update, options)

基本示例

javascript
// 更新第一个匹配的文档
db.users.updateOne(
  { name: "张三" },
  { $set: { age: 26, updatedAt: new Date() } }
)

返回结果

json
{
  "acknowledged": true,
  "matchedCount": 1,
  "modifiedCount": 1
}

更新多个文档

updateMany() 方法

javascript
db.collection.updateMany(filter, update, options)

基本示例

javascript
// 更新所有匹配的文档
db.users.updateMany(
  { status: "inactive" },
  { $set: { status: "active" } }
)

更新操作符

$set - 设置字段值

javascript
// 设置单个字段
db.users.updateOne(
  { name: "张三" },
  { $set: { age: 26 } }
)

// 设置多个字段
db.users.updateOne(
  { name: "张三" },
  { $set: { age: 26, city: "上海" } }
)

// 设置嵌套字段
db.users.updateOne(
  { name: "张三" },
  { $set: { "address.city": "上海" } }
)

// 设置数组元素
db.users.updateOne(
  { name: "张三" },
  { $set: { "tags.0": "VIP" } }
)

$unset - 删除字段

javascript
// 删除字段
db.users.updateOne(
  { name: "张三" },
  { $unset: { tempField: "" } }
)

// 删除多个字段
db.users.updateOne(
  { name: "张三" },
  { $unset: { tempField: "", oldField: "" } }
)

$inc - 增加数值

javascript
// 增加数值
db.users.updateOne(
  { name: "张三" },
  { $inc: { age: 1 } }  // age + 1
)

// 减少数值
db.users.updateOne(
  { name: "张三" },
  { $inc: { age: -1 } }  // age - 1
)

// 增加多个字段
db.products.updateOne(
  { name: "iPhone" },
  { $inc: { stock: -1, sold: 1 } }
)

$mul - 乘以数值

javascript
// 乘以数值
db.products.updateOne(
  { name: "iPhone" },
  { $mul: { price: 0.9 } }  // 价格打9折
)

$rename - 重命名字段

javascript
// 重命名字段
db.users.updateMany(
  {},
  { $rename: { "oldName": "newName" } }
)

数组操作符

$push - 添加元素到数组

javascript
// 添加单个元素
db.users.updateOne(
  { name: "张三" },
  { $push: { tags: "VIP" } }
)

// 添加多个元素
db.users.updateOne(
  { name: "张三" },
  { $push: { tags: { $each: ["VIP", "Premium"] } } }
)

// 添加到指定位置
db.users.updateOne(
  { name: "张三" },
  { $push: { tags: { $each: ["New"], $position: 0 } } }
)

// 排序后限制数量
db.users.updateOne(
  { name: "张三" },
  { $push: { scores: { $each: [85], $sort: -1, $slice: 3 } } }
)

$addToSet - 添加到集合(不重复)

javascript
// 添加不重复元素
db.users.updateOne(
  { name: "张三" },
  { $addToSet: { tags: "VIP" } }
)

// 添加多个不重复元素
db.users.updateOne(
  { name: "张三" },
  { $addToSet: { tags: { $each: ["VIP", "Premium", "VIP"] } } }
)

$pop - 移除数组元素

javascript
// 移除最后一个元素
db.users.updateOne(
  { name: "张三" },
  { $pop: { tags: 1 } }
)

// 移除第一个元素
db.users.updateOne(
  { name: "张三" },
  { $pop: { tags: -1 } }
)

$pull - 移除指定元素

javascript
// 移除指定值
db.users.updateOne(
  { name: "张三" },
  { $pull: { tags: "VIP" } }
)

// 移除多个值
db.users.updateOne(
  { name: "张三" },
  { $pull: { tags: { $in: ["VIP", "Premium"] } } }
)

// 按条件移除
db.users.updateOne(
  { name: "张三" },
  { $pull: { scores: { $lt: 60 } } }
)

$pullAll - 移除所有指定值

javascript
db.users.updateOne(
  { name: "张三" },
  { $pullAll: { tags: ["VIP", "Premium"] } }
)

替换文档

replaceOne() 方法

javascript
db.users.replaceOne(
  { name: "张三" },
  {
    name: "张三",
    age: 26,
    city: "上海"
    // 注意:_id 不会被替换
  }
)

更新选项

upsert - 不存在则插入

javascript
db.users.updateOne(
  { name: "新用户" },
  { $set: { age: 20, createdAt: new Date() } },
  { upsert: true }
)

writeConcern

javascript
db.users.updateOne(
  { name: "张三" },
  { $set: { age: 26 } },
  {
    writeConcern: {
      w: "majority",
      j: true,
      wtimeout: 5000
    }
  }
)

批量更新

批量操作

javascript
var bulk = db.users.initializeUnorderedBulkOp()

bulk.find({ name: "张三" }).updateOne({ $set: { age: 26 } })
bulk.find({ name: "李四" }).updateOne({ $set: { age: 31 } })
bulk.find({ status: "inactive" }).update({ $set: { status: "active" } })

bulk.execute()

更新示例

综合示例

javascript
// 更新用户信息并添加操作日志
db.users.updateOne(
  { _id: ObjectId("...") },
  {
    $set: {
      lastLogin: new Date(),
      loginCount: 1
    },
    $inc: { loginCount: 1 },
    $push: {
      loginHistory: {
        $each: [{ time: new Date(), ip: "192.168.1.1" }],
        $slice: -10  // 只保留最近10条
      }
    }
  }
)

总结

更新文档要点:

  • updateOne() 更新单个文档
  • updateMany() 更新多个文档
  • replaceOne() 替换整个文档
  • 使用各种操作符实现不同更新需求
  • upsert 可实现"存在更新,不存在插入"

在下一章中,我们将学习 MongoDB 删除文档