翻译或纠错本页面

db.collection.update()

说明

db.collection.update(query, update, options)

修改一个或多个集合中已经存在的文档记录。这个方法可以修改一个或多个已经存在的文档记录中的指定字段,或替换整个已经存在的文档记录,具体操作由传入的参数( update parameter)决定。

默认情况下, update() 方法只修改 一个 文档记录。设置 “Multi”选项 参数后可以批量更新匹配查询条件的所有文档记录。

The update() method has the following form:

在 2.6 版更改.

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>
   }
)

The update() method takes the following parameters:

Parameter Type Description
query document

The selection criteria for the update. The same query selectors as in the find() method are available.

在 3.0 版更改: When you execute an update() with upsert: true and the query matches no existing document, MongoDB will refuse to insert a new document if the query specifies conditions on the _id field using dot notation.

For more information and an example, see upsert:true with a Dotted _id Query.

update document The modifications to apply. For details see Update方法的参数.
upsert boolean Optional. If set to true, creates a new document when no document matches the query criteria. The default value is false, which does not insert a new document when no match is found.
multi boolean Optional. If set to true, updates multiple documents that meet the query criteria. If set to false, updates one document. The default value is false. For additional information, see “Multi”选项.
writeConcern document

Optional. A document expressing the write concern. Omit to use the default write concern. See Write Concern.

2.6 新版功能.

collation document

Optional.

Specifies the collation to use for the operation.

Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks.

The collation option has the following syntax:

collation: {
   locale: <string>,
   caseLevel: <boolean>,
   caseFirst: <string>,
   strength: <int>,
   numericOrdering: <boolean>,
   alternate: <string>,
   maxVariable: <string>,
   backwards: <boolean>
}

When specifying collation, the locale field is mandatory; all other collation fields are optional. For descriptions of the fields, see Collation Document.

If the collation is unspecified but the collection has a default collation (see db.createCollection()), the operation uses the collation specified for the collection.

If no collation is specified for the collection or for the operations, MongoDB uses the simple binary comparison used in prior versions for string comparisons.

3.4 新版功能.

在 2.6 版更改: The update() method returns an object that contains the status of the operation.

返回:更新结果对象 ( 操作结果 )中包含本次操作的状态。

行为

Write Concern

在 2.6 版更改.

The update() method uses the update command, which uses the default write concern. To specify a different write concern, include the writeConcern option in the options parameter. See Override Default Write Concern for an example.

Update方法的参数

The update() method either modifies specific fields in existing documents or replaces an existing document entirely.

更新指定的字段

如果 <update> 参数中包含更新操作符( update operator ),也就是使用 $set 操作符时:

  • The <update> document must contain only update operator expressions.
  • The update() method updates only the corresponding fields in the document.

To update an embedded document or an array as a whole, specify the replacement value for the field. To update particular fields in an embedded document or in an array, use dot notation to specify the field.

更新整个文档记录

如果 <update> 参数中 包含 field:value (普通的键值对)表达式,则:

  • The update() method replaces the matching document with the <update> document. The update() method does not replace the _id value. For an example, see 替换全部字段.
  • update() 方法 不会 批量替换文档( update multiple documents )。

更新插(Upsert) 选项

更新插(Upsert) 行为

如果 upsert 选项的值是 true 且没有匹配到查询条件的文档, update() 方法会插入 一条 文档记录。update方法会这样插入一条新文档记录:

  • The fields and values of the <update> parameter if the <update> parameter is a replacement document (i.e., contains only field and value pairs). If neither the <query> nor the <update> document specifies an _id field, MongoDB adds the _id field with an ObjectId value.
  • 如果 <update> 方法传入的参数中 包含更新操作符( update operator )字段,会同时使用传入的 <query><update> 参数。update方法会用 <query> 参数的值创建一个基础文档记录,再把 <update> 参数中的值应用到这个文档记录中。

如果``upsert`` 选项的值是 true 并且匹配到符合查询条件的文档记录, update() 方法会执行更新操作。

参见

操作符 $setOnInsert

使用唯一索引

警告

如果想要避免插入多个同样的文档记录,当 query 参数的字段中有唯一索引时只要使用 upsert: true 选项即可。

如果 people 集合中没有 name 字段的值是 Andy 的记录,把这条记录插进去。要考虑多个用户同时使用下面的的 更新 操作并且都带了 upsert: true 这个选项的情况:

db.people.update(
   { name: "Andy" },
   {
      name: "Andy",
      rating: 1,
      score: 1
   },
   { upsert: true }
)

如果所有的 update() 操作都完成了 query 这部分工作,但没有任何一个用户完成数据写入, 并且 name 字段上没有唯一索引,这时有可能每个 update 操作都插入了一个记录。

为了阻止 Mongodb 插入多条同样的文档记录,需要在 name 字段上创建一个唯一索引 ( unique index )。有了唯一索引,如果多个应用使用同样的包含 upsert: true 选项的更新操作, 只有一个 update() 操作可以成功插入一条新的文档记录。

其余的update操作会:

  • 更新最近插入的文档,或者

  • 尝试插入重复的记录时失败。

    如果因为出现重复的索引键而产生异常操作会失败,应用程序可以再次尝试这个操作,它会被转为更新操作并执行成功。

upsert:true with a Dotted _id Query

When you execute an update() with upsert: true and the query matches no existing document, MongoDB will refuse to insert a new document if the query specifies conditions on the _id field using dot notation.

This restriction ensures that the order of fields embedded in the _id document is well-defined and not bound to the order specified in the query

If you attempt to insert a document in this way, MongoDB will raise an error.

For example, consider the following update operation. Since the update operation specifies upsert:true and the query specifies conditions on the _id field using dot notation, then the update will result in an error when constructing the document to insert.

db.collection.update( { "_id.name": "Robert Frost", "_id.uid": 0 },
   { "categories": ["poet", "playwright"] },
   { upsert: true } )

“Multi”选项

If multi is set to true, the update() method updates all documents that meet the <query> criteria. The multi update operation may interleave with other operations, both read and/or write operations. For unsharded collections, you can override this behavior with the $isolated operator, which isolates the update operation and disallows yielding during the operation. This isolates the update so that no client can see the updated documents until they are all processed, or an error stops the update operation.

如果update参数 ( <update> )传入的文档参数中 包含 “键:值” 格式的数据(不包含其他操作符), update() 操作 不会 一次更新多条记录。

示例,参见 Update Multiple Documents

分片集合

All update() operations for a sharded collection must include the shard key or the _id field in the query specification. update() operations without the shard key or the _id field return an error.

示例

更新指定的字段

To update specific fields in a document, use update operators in the <update> parameter.

示例,操作 books 集合并传入如下文档作为参数:

{
  _id: 1,
  item: "TBD",
  stock: 0,
  info: { publisher: "1111", pages: 430 },
  tags: [ "technology", "computer" ],
  ratings: [ { by: "ijk", rating: 4 }, { by: "lmn", rating: 5 } ],
  reorder: false
}

The following operation uses:

  • the $inc operator to increment the stock field; and
  • the $set operator to replace the value of the item field, the publisher field in the info embedded document, the tags field, and the second element in the ratings array.
db.books.update(
   { _id: 1 },
   {
     $inc: { stock: 5 },
     $set: {
       item: "ABC123",
       "info.publisher": "2222",
       tags: [ "software" ],
       "ratings.1": { by: "xyz", rating: 3 }
     }
   }
)

The updated document is the following:

{
  "_id" : 1,
  "item" : "ABC123",
  "stock" : 5,
  "info" : { "publisher" : "2222", "pages" : 430 },
  "tags" : [ "software" ],
  "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
  "reorder" : false
}

删除字段

The following operation uses the $unset operator to remove the tags field:

db.books.update( { _id: 1 }, { $unset: { tags: 1 } } )

替换全部字段

books 集合中传入如下文档:

{
  _id: 2,
  item: "XYZ123",
  stock: 15,
  info: { publisher: "5555", pages: 150 },
  tags: [ ],
  ratings: [ { by: "xyz", rating: 5, comment: "ratings and reorder will go away after update"} ],
  reorder: false
}

下面的操作给 <update> 参数传入一个只包含键值对的文档,表示用新的文档替换原有文档中的所有字段。这个操作 不会 替换 _id 的值。如果给 <query> 参数和 <update> 参数传入的文档的键和值完全相同,就表示没有需要修改的字段:

db.books.update(
   { item: "XYZ123" },
   {
     item: "XYZ123",
     stock: 10,
     info: { publisher: "2255", pages: 150 },
     tags: [ "baking", "cooking" ]
   }
)

这个操作会创建如下新文档。这个操作会删除 author 字段并修改 pricestock 字段的值:

{
   "_id" : 2,
   "item" : "XYZ123",
   "stock" : 10,
   "info" : { "publisher" : "2255", "pages" : 150 },
   "tags" : [ "baking", "cooking" ]
}

如果没有匹配的记录,插入一个新的文档记录

下面这个操作把更新插( upsert )选项设置成 true ,所以 update() 操作在 books 集合中找不到能匹配 <query> 参数的文档时会创建一个新的文档记录。

db.books.update(
   { item: "ZZZ135" },
   {
     item: "ZZZ135",
     stock: 5,
     tags: [ "database" ]
   },
   { upsert: true }
)

如果没有能匹配上 <query> 参数的文档, update 操作会用 <update> 参数传入的的文档参数创建一个新的记录,并给这个条记录的 _id 字段一个``ObjectId`` 类型的唯一值:

{
  "_id" : ObjectId("542310906694ce357ad2a1a9"),
  "item" : "ZZZ135",
  "stock" : 5,
  "tags" : [ "database" ]
}

For more information on upsert option and the inserted document, 更新插(Upsert) 选项.

Update Multiple Documents

To update multiple documents, set the multi option to true. For example, the following operation updates all documents where stock is less than or equal to 10:

db.books.update(
   { stock: { $lte: 10 } },
   { $set: { reorder: true } },
   { multi: true }
)

如果不知道数组中的位置, update() 操作中可以使用位置操作符 $ 。为了定位要更新数组元素,这个数组字段必须出现在 <query> 参数中。

Override Default Write Concern

The following operation on a replica set specifies a write concern of "w: majority" with a wtimeout of 5000 milliseconds such that the method returns after the write propagates to a majority of the voting replica set members or the method times out after 5 seconds.

在 3.0 版更改: In previous versions, majority referred to the majority of all members of the replica set instead of the majority of the voting members.

db.books.update(
   { stock: { $lte: 10 } },
   { $set: { reorder: true } },
   {
     multi: true,
     writeConcern: { w: "majority", wtimeout: 5000 }
   }
)

Combine the upsert and multi Options

Given a books collection that includes the following documents:

{
  _id: 5,
  item: "EFG222",
  stock: 18,
  info: { publisher: "0000", pages: 70 },
  reorder: true
}
{
  _id: 6,
  item: "EFG222",
  stock: 15,
  info: { publisher: "1111", pages: 72 },
  reorder: true
}

The following operation specifies both the multi option and the upsert option. If matching documents exist, the operation updates all matching documents. If no matching documents exist, the operation inserts a new document.

db.books.update(
   { item: "EFG222" },
   { $set: { reorder: false, tags: [ "literature", "translated" ] } },
   { upsert: true, multi: true }
)

The operation updates all matching documents and results in the following:

{
   "_id" : 5,
   "item" : "EFG222",
   "stock" : 18,
   "info" : { "publisher" : "0000", "pages" : 70 },
   "reorder" : false,
   "tags" : [ "literature", "translated" ]
}
{
   "_id" : 6,
   "item" : "EFG222",
   "stock" : 15,
   "info" : { "publisher" : "1111", "pages" : 72 },
   "reorder" : false,
   "tags" : [ "literature", "translated" ]
}

If the collection had no matching document, the operation would result in the insertion of a document using the fields from both the <query> and the <update> specifications:

{
   "_id" : ObjectId("5423200e6694ce357ad2a1ac"),
   "item" : "EFG222",
   "reorder" : false,
   "tags" : [ "literature", "translated" ]
}

For more information on upsert option and the inserted document, 更新插(Upsert) 选项.

Specify Collation

3.4 新版功能.

Collation allows users to specify language-specific rules for string comparison, such as rules for lettercase and accent marks.

A collection myColl has the following documents:

{ _id: 1, category: "café", status: "A" }
{ _id: 2, category: "cafe", status: "a" }
{ _id: 3, category: "cafE", status: "a" }

The following operation includes the collation option:

db.myColl.update(
   { category: "cafe" },
   { $set: { status: "Updated" } },
   { collation: { locale: "fr", strength: 1 } }
);

操作结果

在 2.6 版更改.

操作成功

The update() method returns a WriteResult object that contains the status of the operation. Upon success, the WriteResult object contains the number of documents that matched the query condition, the number of documents inserted by the update, and the number of documents modified:

WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

写确认异常

如果 update() 操作遇到“写确认异常”,返回的结果中会包 WriteResult.writeConcernError 字段:

WriteResult({
   "nMatched" : 1,
   "nUpserted" : 0,
   "nModified" : 1,
   "writeConcernError" : {
      "code" : 64,
      "errmsg" : "waiting for replication timed out at shard-a"
   }
})

与写确认无关的异常

如果 update() 操作遇到一个与写确认无关的异常,返回结果中会包含 WriteResult.writeError 字段:

WriteResult({
   "nMatched" : 0,
   "nUpserted" : 0,
   "nModified" : 0,
   "writeError" : {
      "code" : 7,
      "errmsg" : "could not contact primary for replica set shard-a"
   }
})

Additional Resources