翻译或纠错本页面

更新文档

更新

MongoDB提供如下方法更新集合中的文档:

db.collection.updateOne()

即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新一个文档。

3.2 新版功能.

db.collection.updateMany()

更新所有通过过滤条件匹配到的文档.

3.2 新版功能.

db.collection.replaceOne()

即使可能有多个文档通过过滤条件匹配到,但是也最多也只替换一个文档。

3.2 新版功能.

db.collection.update()

即使可能有多个文档通过过滤条件匹配到,但是也最多也只更新或者替换一个文档。

默认情况下, db.collection.update() 只更新 一个 文档。要更新多个文档,请使用 multi 选项。

这些方法接收(如下)参数:

  • 过滤条件文档—-决定更些哪些文档。 这些 文档过滤查询 使用和读操作相同的语法:

    • 查询过滤文档 能够用 <field>:<value> 表达式指定相等条件并以此选出所有包含有指定 <value><field> 的文档:

      { <field1>: <value1>, ... }
      
    • 查询过滤文档 能使用以下 ref:查询操作符 <query-selectors> 来指定查询条件:

      { <field1>: { <operator1>: <value1> }, ... }
      
  • 更新文档—-指定要执行的修改或替换文档—完全替换匹配文档(除了 _id 字段)

  • 选项文档

行为表现

原子性

MongoDB中所有的写操作在单一文档层级上是原子的。更多关于MongoDB和原子性的信息,请参见 原子性和事务处理

_id 字段

一旦设定,你不能更新 _id 字段的值,你也不能用有不同 _id 字段值的替换文档来替换已经存在的文档。

文档大小

当执行更新操作增加的文档大小超过了为该文档分配的空间时。更新操作会在磁盘上重定位该文档。

字段顺序

MongoDB按照文档写入的顺序整理文档字段,除了 如下的情况:

  • _id 字段始终是文档中的第一个字段。

  • 包括字段名称的 renaming 操作可能会导致文档中的字段重新排序。

在 2.6 版更改: 从2.6版本开始,MongoDB主动尝试保持字段在文档中的顺序。 2.6版本之前,MongoDB不会主动保持文档中的字段的顺序。

Upsert 选项

如果 db.collection.update()db.collection.updateOne()db.collection.updateMany() 或者 db.collection.replaceOne() 包含 upsert : true 并且 没有文档匹配指定的过滤器,那么此操作会创建一个新文档并插入它。如果有匹配的文档,那么此操作修改或替换匹配的单个或多个文档。

更多关于新文档创建的细节,请参考该方法的详细页。

示例集合

本页示例使用 mongo shell 中的 db.collection.find() 方法。在 mongo shell 中,如果返回的游标没有赋给使用 var 关键字的变量,那么该游标会自动迭代20次 [1] 来打印出结果中的前20个文档。

要添加示例中涉及的 users 集合,在 mongo shell中运行如下命令:

注解

如果 users 集合中已经包含了相同 _id 值的文档,你需要在插入示例文档前 drop 该集合( db.users.drop() )。

db.users.insertMany(
   [
     {
       _id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: { artist: "Picasso", food: "pizza" },
       finished: [ 17, 3 ],
       badges: [ "blue", "black" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 85, bonus: 10 }
       ]
     },
     {
       _id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: { artist: "Miro", food: "meringue" },
       finished: [ 11, 25 ],
       badges: [ "green" ],
       points: [
          { points: 85, bonus: 20 },
          { points: 64, bonus: 12 }
       ]
     },
     {
       _id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: { artist: "Cassatt", food: "cake" },
       finished: [ 6 ],
       badges: [ "blue", "Picasso" ],
       points: [
          { points: 81, bonus: 8 },
          { points: 55, bonus: 20 }
       ]
     },
     {
       _id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: { artist: "Chagall", food: "chocolate" },
       finished: [ 5, 11 ],
       badges: [ "Picasso", "black" ],
       points: [
          { points: 53, bonus: 15 },
          { points: 51, bonus: 15 }
       ]
     },
     {
       _id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: { artist: "Noguchi", food: "nougat" },
       finished: [ 14, 6 ],
       badges: [ "orange" ],
       points: [
          { points: 71, bonus: 20 }
       ]
     },
     {
       _id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: { food: "pizza", artist: "Picasso" },
       finished: [ 18, 12 ],
       badges: [ "black", "blue" ],
       points: [
          { points: 78, bonus: 8 },
          { points: 57, bonus: 7 }
       ]
     }
   ]
)

更新文档中指定字段

为了修改文档中的字段,MongoDB 提供了 update operators,例如用来修改值的 $set

为了用update操作执行指定的修改操作,可以使用如下更新文档的形式。

{
   <update operator>: { <field1>: <value1>, ... },
   <update operator>: { <field2>: <value2>, ... },
   ...
}

像:update:$set`这样的更新操作符,如果字段不存在则会创建字段。具体参考手册 :manual:`update operator</reference/operator/update>

db.collection.updateOne()

3.2 新版功能.

下面的例子对 users 集合使用 db.collection.updateOne() 方法来更新*第一个* 根据 过滤条件``favorites.artist`` 等于 "Picasso" 匹配到的文档更新操作:

  • 使用 $set 操作符更新 favorites.food 字段的值为 "pie" 并更新 type 字段的值为 3,

  • 使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $currentDate.

db.users.updateOne(
   { "favorites.artist": "Picasso" },
   {
     $set: { "favorites.food": "pie", type: 3 },
     $currentDate: { lastModified: true }
   }
)

更多信息和例子请参考 db.collection.updateOne()

db.collection.updateMany()

3.2 新版功能.

下面的例子对 users 集合使用 db.collection.updateMany() 方法来更新所有根据过滤条件 favorites.artist 等于 "Picasso" 匹配的文档。更新操作:

  • 使用 $set 操作符更新 favorites.food 字段的值为 "Pisanello" 并更新 type 字段的值为 3,

  • 使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $currentDate.

db.users.updateMany(
   { "favorites.artist": "Picasso" },
   {
     $set: { "favorites.artist": "Pisanello", type: 3 },
     $currentDate: { lastModified: true }
   }
)

更多信息和例子请参考: db.collection.updateMany()

db.collection.update

下面的例子对 users 集合使用 db.collection.update() 方法来更新根据过滤条件 favorites.artist 等于 "Pisanello" 匹配的 第一个 文档。更新操作:

  • 使用 $set 操作符把 favorites.food 字段值更新为 "pizza" 并且把 type 字段的值更新为 0

  • 使用 $currentDate 操作符更新 lastModified 字段的值到当前日期。如果 lastModified 字段不存在, $currentDate 会创建该字段。详情请参阅 $currentDate.

db.users.update(
   { "favorites.artist": "Pisanello" },
   {
     $set: { "favorites.food": "pizza", type: 0,  },
     $currentDate: { lastModified: true }
   }
)

使用 db.collection.update() 并包含 multi: true 选项来更新多个文档:

db.users.update(
   { "favorites.artist": "Pisanello" },
   {
     $set: { "favorites.food": "pizza", type: 0,  },
     $currentDate: { lastModified: true }
   },
   { multi: true }
)

文档替换

要更新除 _id 字段外文档的整个内容,传递一个全新的文档给 db.collection.replaceOne() 或者 db.collection.update() 作为第二个参数。当替换文档时,替换的文档必须仅仅由 <field> : <value> 组成.

替换文档可以有不同于原文档的字段。在替换文档中,由于 _id 字段是不变的,所以,你可以省略 _id 字段;不论如何,如果你包含了 _id 字段,它的值必须和当前的值相同。

db.collection.replaceOne

下面的例子对 users 集合使用 db.collection.replaceOne() 方法将通过过滤条件 name 等于 "sue" 匹配到的 第一个 文档替换为新文档:

db.users.replaceOne(
   { name: "abc" },
   { name: "amy", age: 34, type: 2, status: "P", favorites: { "artist": "Dali", food: "donuts" } }
)

db.collection.update

下面的例子对 users 集合使用 db.collection.update() 方法将通过过滤条件 name 等于 "xyz" 匹配到的 第一个 文档替换为新文档:

db.users.update(
   { name: "xyz" },
   { name: "mee", age: 25, type: 1, status: "A", favorites: { "artist": "Matisse", food: "mango" } }
)

其他方法

如下方法也可以更新一个集合的文档:

更多信息和例子请参见该方法的参考页。

写确认

在安全写情况下,你可以指定MongoDB写操作要求的确认级别。详情请参见 Write Concern

[1]

你可以使用``DBQuery.shellBatchSize`` 来改变迭代结果的数量,默认是展示20条记录。 更多信息请参考 使用``mongo`` Shell