<返回目录     Powered by claud/xia兄

第6课: 更新操作

updateOne() - 更新单个文档

// 更新第一个匹配的文档
db.users.updateOne(
    { name: "张三" },           // 查询条件
    { $set: { age: 26 } }       // 更新操作
)

// 返回结果
{
    acknowledged: true,
    matchedCount: 1,
    modifiedCount: 1
}

updateMany() - 更新多个文档

// 更新所有匹配的文档
db.users.updateMany(
    { city: "北京" },
    { $set: { region: "华北" } }
)

// 返回结果
{
    acknowledged: true,
    matchedCount: 15,
    modifiedCount: 15
}

replaceOne() - 替换文档

// 完全替换文档(保留_id)
db.users.replaceOne(
    { name: "张三" },
    {
        name: "张三",
        age: 26,
        email: "zhangsan@new.com",
        city: "上海"
    }
)
注意:

replaceOne会替换整个文档,除了_id字段。如果只想更新部分字段,使用updateOne配合$set。

$set - 设置字段值

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

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

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

$unset - 删除字段

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

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

$inc - 增加数值

// 增加年龄1岁
db.users.updateOne(
    { name: "张三" },
    { $inc: { age: 1 } }
)

// 减少库存(负数)
db.products.updateOne(
    { _id: "prod123" },
    { $inc: { stock: -5 } }
)

// 增加多个字段
db.posts.updateOne(
    { _id: ObjectId("...") },
    { $inc: { views: 1, likes: 1 } }
)

$mul - 乘法运算

// 价格打8折
db.products.updateMany(
    { category: "电子产品" },
    { $mul: { price: 0.8 } }
)

$rename - 重命名字段

// 重命名字段
db.users.updateMany(
    {},
    { $rename: { "phone": "mobile" } }
)

$min 和 $max

// 只在新值更小时更新
db.products.updateOne(
    { _id: "prod123" },
    { $min: { price: 99 } }
)

// 只在新值更大时更新
db.users.updateOne(
    { name: "张三" },
    { $max: { highScore: 1500 } }
)

$currentDate - 设置当前日期

// 设置为当前日期
db.users.updateOne(
    { name: "张三" },
    { $currentDate: { lastModified: true } }
)

// 设置为时间戳
db.users.updateOne(
    { name: "张三" },
    { $currentDate: { lastModified: { $type: "timestamp" } } }
)

数组更新操作符

// $push - 添加元素到数组
db.users.updateOne(
    { name: "张三" },
    { $push: { hobbies: "游泳" } }
)

// $push + $each - 添加多个元素
db.users.updateOne(
    { name: "张三" },
    { $push: { hobbies: { $each: ["游泳", "跑步"] } } }
)

// $pull - 删除匹配的元素
db.users.updateOne(
    { name: "张三" },
    { $pull: { hobbies: "游泳" } }
)

// $pop - 删除第一个或最后一个元素
db.users.updateOne(
    { name: "张三" },
    { $pop: { hobbies: 1 } }   // 1删除最后一个,-1删除第一个
)

// $addToSet - 添加元素(不重复)
db.users.updateOne(
    { name: "张三" },
    { $addToSet: { hobbies: "读书" } }
)

upsert选项

// upsert: true - 不存在则插入
db.users.updateOne(
    { name: "新用户" },
    { $set: { age: 25, city: "北京" } },
    { upsert: true }
)

// 如果文档不存在,会创建新文档

实战示例

// 电商系统:用户下单后更新库存和销量
db.products.updateOne(
    { _id: "prod123", stock: { $gte: 5 } },
    {
        $inc: { stock: -5, sales: 5 },
        $set: { lastSoldAt: new Date() }
    }
)

// 社交系统:用户点赞文章
db.posts.updateOne(
    { _id: ObjectId("...") },
    {
        $inc: { likes: 1 },
        $addToSet: { likedBy: "user123" }
    }
)

// 批量更新:所有过期商品下架
db.products.updateMany(
    { expiryDate: { $lt: new Date() } },
    {
        $set: { status: "expired", onSale: false },
        $currentDate: { updatedAt: true }
    }
)
练习题:
  1. 将所有北京用户的年龄增加1岁
  2. 给用户"张三"添加一个新爱好"摄影"
  3. 将商品价格大于1000的商品打9折
  4. 删除所有用户的临时字段"tempData"
  5. 更新文章浏览量,每次访问增加1
  6. 使用upsert创建或更新用户配置