基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

MongoDB 常用的更新修饰符(Update Modifiers)有哪些?

知识点图片

MongoDB 的更新修饰符(Update Modifiers/Operators)是用于在 updateupdateOneupdateManyfindOneAndUpdate 等操作中修改文档内容的特殊关键字。它们以 $ 符号开头。

为了方便记忆和查阅,我将它们分为 字段类数组类修饰类 三大类。


一、 字段更新操作符 (Field Update Operators)

这些操作符用于修改文档中某个具体字段的值。

操作符 描述 示例
$set 最常用。设置字段的值。如果字段不存在,则创建该字段。 { $set: { status: "active", age: 25 } }
$unset 删除指定的字段。值通常设为 ""1(值不重要)。 { $unset: { temporary_field: "" } }
$inc 对数值字段进行增减(原子操作)。传入负数即为减。 { $inc: { views: 1, balance: -100 } }
$mul 将字段的值乘以指定的数值。 { $mul: { price: 1.1 } } (涨价 10%)
$rename 重命名字段名称。 { $rename: { "oldName": "newName" } }
$min 仅当指定值小于当前字段值时才更新(保留最小值)。 { $min: { best_score: 98 } }
$max 仅当指定值大于当前字段值时才更新(保留最大值)。 { $max: { high_score: 500 } }
$currentDate 将字段值设置为当前日期/时间(Date 或 Timestamp 类型)。 { $currentDate: { lastModified: true } }
$setOnInsert 配合 upsert: true 使用。仅在插入新文档时设置字段,如果是更新旧文档则不执行。 { $setOnInsert: { createdAt: new Date() } }

二、 数组更新操作符 (Array Update Operators)

这些操作符专门用于处理数组类型的字段。

操作符 描述 示例
$push 向数组末尾添加一个元素。 { $push: { tags: "mongodb" } }
$addToSet 向数组添加元素,但只有当该元素不存在时才添加(保证数组唯一性)。 { $addToSet: { tags: "database" } }
$pop 删除数组中的第一个或最后一个元素。
1: 删除最后一个;-1: 删除第一个。
{ $pop: { items: 1 } }
$pull 删除数组中匹配特定条件的所有元素。 { $pull: { tags: "outdated" } }
{ $pull: { users: { age: { $lt: 18 } } } }
$pullAll 删除数组中包含在指定列表中的所有值(完全匹配)。 { $pullAll: { scores: [0, 5] } }

三、 $push 的修饰符 (Modifiers for $push)

在使用 $push 时,可以配合以下修饰符来控制插入行为(例如一次插入多个、排序、限制长度)。

修饰符 描述 示例
$each 配合 $push$addToSet 使用,一次添加多个值。 { $push: { scores: { $each: [90, 85, 99] } } }
$slice 配合 $push 使用,限制数组的最大长度。0 清空,负数保留最后 N 个。 { $push: { logs: { $each: [newLog], $slice: -5 } } } (只保留最后5条)
$sort 配合 $push 使用,在插入后对数组进行排序。 { $push: { scores: { $each: [70], $sort: -1 } } } (插入后降序排列)
$position 配合 $push 使用,指定插入的位置(索引)。 { $push: { list: { $each: ["top"], $position: 0 } } } (插到头部)

四、 数组占位符 (Array Positional Operators)

当你不知道数组元素的具体索引,但想更新匹配查询条件的那个元素时使用。

占位符 描述 示例
$ 更新第一个匹配查询条件的数组元素。 db.coll.updateOne({ "grades.grade": 80 }, { $set: { "grades.$.std": 2 } })
$[] 更新数组中的所有元素。 { $inc: { "grades.$[].score": 10 } } (所有成绩加10分)
$[<identifier>] 配合 arrayFilters 选项,更新满足特定条件的元素。 update(..., { $set: { "grades.$[elem].score": 100 } }, { arrayFilters: [ { "elem.score": { $gte: 90 } } ] })

常见场景举例

1. 用户点赞(计数器 +1):

javascript
db.posts.updateOne(
  { _id: 123 },
  { $inc: { likes: 1 } }
);

2. 修改用户信息(如果不存在则创建,记录创建时间):

javascript
db.users.updateOne(
  { _id: 1 },
  {
    $set: { name: "Alice", lastLogin: new Date() },
    $setOnInsert: { createdAt: new Date() } // 只有是新插入时才写入 createdAt
  },
  { upsert: true }
);

3. 给文章添加标签(不重复添加):

javascript
db.articles.updateOne(
  { _id: 123 },
  { $addToSet: { tags: "tech" } }
);

4. 维护一个固定长度的日志数组(只保留最近 100 条):

javascript
db.logs.updateOne(
  { _id: 1 },
  {
    $push: {
      history: {
        $each: ["New Log Entry"],
        $slice: -100  // 负数表示保留最后 100 个
      }
    }
  }
);
00:00
00:00