db.collection.update()

在本页面

Definition

默认情况下,update()方法更新一个**文档。设置Multi Parameter以更新所有符合查询条件的文档。

update()方法具有以下形式:

在版本 3.6 中更改。

db.collection.update(
   <query>,
   <update>,
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ]
   }
)

update()方法采用以下参数:

Parameter Type Description
query document 更新的选择标准。与find()方法中相同的query selectors可用。


在版本 3.0 中进行了更改:当您使用upsert: true执行update()并且查询与现有文档不匹配时,如果查询使用dot notation_id字段中指定了条件,则 MongoDB 将拒绝插入新文档。
有关更多信息和示例,请参见upsert:true,带有虚线_id 查询
| update | document |要应用的修改。有关详细信息,请参见Update Parameter
| upsert |布尔值|可选。如果设置为true,则在没有文档符合查询条件时创建一个新文档。 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |的缺省值false不会在没有匹配时插入新文档。
| multi |布尔值|可选。如果设置为true,则更新满足query标准的多个文档。如果设置为false,则更新一个文档。默认值为false。有关更多信息,请参见Multi Parameter
| writeConcern |文档|可选。表示write concern的文档。省略使用默认的写关注。参见Write Concern
2.6 版中的新功能。
| collation |文档|可选。
指定用于操作的collation
Collation允许用户为字符串比较指定特定于语言的规则,例如字母大写和重音符号的规则。
排序规则选项具有以下语法:
collation: {
locale: <string>,
caseLevel: <boolean>,
caseFirst: <string>,
strength: <int>,
numericOrdering: <boolean>,
alternate: <string>,
maxVariable: <string>,
backwards: <boolean>
}
指定排序规则时,locale字段为必填字段;所有其他排序规则字段都是可选的。有关字段的说明,请参见Collation Document
如果未指定排序规则,但是集合具有默认排序规则(请参见db.createCollection()),则该操作将使用为集合指定的排序规则。
如果没有为集合或操作指定排序规则,则 MongoDB 使用先前版本中使用的简单二进制比较进行字符串比较。
您不能为一个操作指定多个排序规则。例如,您不能为每个字段指定不同的排序规则,或者如果对排序执行查找,则不能对查找使用一种排序规则,而对排序使用另一种排序规则。
3.4 版中的新功能。
| arrayFilters | array |可选。筛选器文档数组,用于确定要对数组字段进行更新操作要修改的数组元素。
在更新文档中,使用$[<identifier>]过滤的位置运算符定义标识符,然后在数组过滤器文档中引用该标识符。如果更新文档中未包含标识符,则不能具有数组过滤器文档作为标识符。

Note





<identifier>必须以小写字母开头,并且只能包含字母数字字符。



您可以在更新文档中多次包含相同的标识符;但是,对于更新文档中的每个唯一标识符($[identifier]),您必须指定**完全对应的数组过滤器文档。即,您不能为同一标识符指定多个数组过滤器文档。例如,如果更新语句包含标识符x(可能多次),则不能为arrayFilters指定以下内容,其中包括x的 2 个单独的过滤器文档:
[
{ "x.a": { $gt: 85 } },
{ "x.b": { $gt: 80 } }
br]
但是,您可以在单个过滤器文档中的同一标识符上指定复合条件,例如以下示例:
[
{ $or: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
[
{ $and: [{"x.a": {$gt: 85}}, {"x.b": {$gt: 80}}] }
]
[
{ "x.a": { $gt: 85 },“ x.b”:{ $gt: 80 }}
br]
有关示例,请参见为阵列更新操作指定 arrayFilters
3.6 版中的新功能。

Returns: 包含操作状态的WriteResult对象。

Behavior

Write Concern

在 2.6 版中进行了更改。

update()方法使用update命令,该命令使用默认的write concern。要指定其他写关注点,请在 options 参数中包含writeConcern选项。有关示例,请参见覆盖默认写问题

Update Parameter

update()方法可以修改现有文档中的特定字段,也可以完全替换现有文档。

更新特定字段

如果<update>文档包含update operator修饰符,例如使用$set修饰符的修饰符,则:

要整体更新嵌入式文档或数组,请为该字段指定替换值。要更新嵌入式文档或数组中的特定字段,请使用dot notation指定该字段。

完全替换文档

如果<update>文档仅包含* field:value个表达式,则:

Upsert Option

Upsert Behavior

如果upserttrue并且没有文档符合查询条件,则update()插入***文档。更新使用以下任一方法创建新文档:

如果upserttrue并且存在符合查询条件的文档,则update()执行更新。

See also

$setOnInsert

使用唯一索引

Warning

为避免多次插入同一文档,如果query字段已唯一索引,则仅使用upsert: true

给定一个名为people的集合,其中没有文档具有name字段的值Andy。考虑多个 Client 端同时使用upsert: true发出以下* update *的情况:

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

如果所有update()操作都在任何 Client 端成功插入数据之前完成query部分,并且name字段上没有唯一索引,则每个更新操作都可能导致插入。

为了防止 MongoDB 多次插入同一文档,请在name字段上创建unique index。使用唯一索引,如果多个应用程序使用upsert: true发出相同的更新,正好一个 update()将成功插入新文档。

其余操作将是:

如果操作由于重复的索引键错误而失败,则应用程序可以重试该操作,该操作将作为更新操作成功。

upsert:true,带有点_id 查询

当您使用upsert: true执行update()并且查询不匹配现有文档时,如果查询使用dot notation_id字段中指定条件,则 MongoDB 将拒绝插入新文档。

此限制可确保正确定义_id文档中嵌入的字段的 Sequences,并且不与查询中指定的 Sequences 绑定

如果您尝试以这种方式插入文档,MongoDB 将引发错误。

例如,考虑以下更新操作。由于更新操作指定upsert:true且查询使用点表示法在_id字段上指定条件,因此在构造要插入的文档时,更新将导致错误。

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

Multi Parameter

如果multi设置为true,则update()方法更新所有符合<query>标准的文档。 multi更新操作可以与其他操作(读和/或写操作)交织。

如果<update>文档仅包含field:value个表达式,则update() 不能更新多个文档。

有关示例,请参见更新多个文件

Sharded Collections

指定justOne选项的分片集合的所有update()操作必须在查询规范中包含shard key _id字段。在分片集合中指定justOneupdate()操作不包含shard key_id字段都将返回错误。

See also

findAndModify()

Examples

更新特定字段

要更新文档中的特定字段,请在<update>参数中使用update operators

例如,给定一个具有以下文档的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
}

以下操作使用:

db.books.update(
   { _id: 1 },
   {
     $inc: { stock: 5 },
     $set: {
       item: "ABC123",
       "info.publisher": "2222",
       tags: [ "software" ],
       "ratings.1": { by: "xyz", rating: 3 }
     }
   }
)

更新后的文档如下:

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

Remove Fields

以下操作使用$unset运算符删除tags字段:

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>文档。 <update>文档完全替换了原始文档,但_id字段除外。

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

更新的文档仅包含替换文档中的字段和_id字段。也就是说,由于更新文档中没有字段ratingsreorder,因此它们不在替换文档中。

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

如果不存在匹配项,则插入新文档

以下更新将upsert选项设置为true,以便在没有文档与<query>参数匹配的情况下update()books集合中创建一个新文档:

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

如果没有文档与<query>参数匹配,则更新操作会插入一个文档,其中 <update>文档的字段和值以及_id字段的新唯一ObjectId

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

有关upsert选项和插入的文档Upsert Option的更多信息。

更新多个文档

要更新多个文档,请将multi选项设置为true。例如,以下操作将更新stock小于或等于10的所有文档:

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

如果匹配的文档中不存在reorder字段,则$set运算符将添加具有指定值的字段。有关更多信息,请参见$set

覆盖默认写问题

对副本集的以下操作指定"w: majority"write concernwtimeout的 5000 毫秒,从而使该方法在写入传播到大多数有表决权的副本集成员之后返回,或者该方法在 5 秒后超时。

在版本 3.0 中进行了更改:在以前的版本中,majority引用了副本集的所有成员的大多数,而不是多数投票成员。

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

组合 upsert 和多个选项

给定一个books集合,其中包含以下文档:

{
  _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
}

以下操作同时指定了multi选项和upsert选项。如果存在匹配的文档,则该操作将更新所有匹配的文档。如果不存在匹配的文档,则该操作将插入一个新文档。

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

该操作将更新所有匹配的文档,并产生以下结果:

{
   "_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" ]
}

如果集合没有匹配的文档,则该操作将使用<query><update>规范中的字段插入文档:

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

有关upsert选项和插入的文档Upsert Option的更多信息。

Specify Collation

3.4 版的新功能。

Collation允许用户为字符串比较指定特定于语言的规则,例如字母大写和重音符号的规则。

集合myColl具有以下文档:

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

以下操作包括collation选项:

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

为阵列更新操作指定 arrayFilters

3.6 版的新功能。

从 MongoDB 3.6 开始,在更新数组字段时,您可以指定arrayFilters来确定要更新的数组元素。

更新元素匹配 arrayFilters 条件

创建包含以下文档的集合students

db.students.insert([
   { "_id" : 1, "grades" : [ 95, 92, 90 ] },
   { "_id" : 2, "grades" : [ 98, 100, 102 ] },
   { "_id" : 3, "grades" : [ 95, 110, 100 ] }
])

要更新grades数组中所有等于或大于100的元素,请使用带有arrayFilters选项的过滤后的位置运算符$[<identifier>]

db.students.update(
   { grades: { $gte: 100 } },
   { $set: { "grades.$[element]" : 100 } },
   {
     multi: true,
     arrayFilters: [ { "element": { $gte: 100 } } ]
   }
)

操作后,集合包含以下文档:

{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 100, 100 ] }

更新一系列文档的特定元素

考虑包含以下文档的集合students2

{
   "_id" : 1,
   "grades" : [
      { "grade" : 80, "mean" : 75, "std" : 6 },
      { "grade" : 85, "mean" : 90, "std" : 4 },
      { "grade" : 85, "mean" : 85, "std" : 6 }
   ]
}
{
   "_id" : 2,
   "grades" : [
      { "grade" : 90, "mean" : 75, "std" : 6 },
      { "grade" : 87, "mean" : 90, "std" : 3 },
      { "grade" : 85, "mean" : 85, "std" : 4 }
   ]
}

要为grades数组中坡度大于或等于85的所有元素修改mean字段的值,请使用过滤后的位置运算符$[<identifier>]arrayFilters

db.students2.update(
   { },
   { $set: { "grades.$[elem].mean" : 100 } },
   {
     multi: true,
     arrayFilters: [ { "elem.grade": { $gte: 85 } } ]
   }
)

操作后,集合具有以下文档:

{
   "_id" : 1,
   "grades" : [
      { "grade" : 80, "mean" : 75, "std" : 6 },
      { "grade" : 85, "mean" : 100, "std" : 4 },
      { "grade" : 85, "mean" : 100, "std" : 6 }
   ]
}
{
   "_id" : 2,
   "grades" : [
      { "grade" : 90, "mean" : 100, "std" : 6 },
      { "grade" : 87, "mean" : 100, "std" : 3 },
      { "grade" : 85, "mean" : 100, "std" : 4 }
   ]
}

WriteResult

在 2.6 版中进行了更改。

Successful Results

update()方法返回包含操作状态的WriteResult对象。成功后,WriteResult对象包含符合查询条件的文档数,更新插入的文档数以及修改的文档数:

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"
   }
})
首页