Definition定义
updateTheupdatecommand modifies documents in a collection. A singleupdatecommand can contain multiple update statements.update命令用于修改集合中的文档。一个update命令可以包含多个更新语句。Tip
In在mongosh, this command can also be run through theupdateOne(),updateMany(),replaceOne(),findOneAndReplace(), andfindOneAndUpdate()helper methods.mongosh中,此命令也可以通过updateOne()、updateMany()、replaceOne(),findOneAndReplace()和findOneAndUpdate()辅助方法运行。Helper methods are convenient for助手方法对mongoshusers, but they may not return the same level of information as database commands. In cases where the convenience is not needed or the additional return fields are required, use the database command.mongosh用户来说很方便,但它们可能不会返回与数据库命令相同级别的信息。如果不需要便利性或需要额外的返回字段,请使用数据库命令。
Compatibility兼容性
This command is available in deployments hosted in the following environments:此命令在以下环境中托管的部署中可用:
- MongoDB Atlas
: The fully managed service for MongoDB deployments in the cloud:云中MongoDB部署的完全托管服务
Note
This command is supported in all MongoDB Atlas clusters. For information on Atlas support for all commands, see Unsupported Commands.所有MongoDB Atlas集群都支持此命令。有关Atlas支持所有命令的信息,请参阅不支持的命令。
- MongoDB Enterprise
: The subscription-based, self-managed version of MongoDB:MongoDB的基于订阅的自我管理版本 - MongoDB Community
: The source-available, free-to-use, and self-managed version of MongoDB:MongoDB的源代码可用、免费使用和自我管理版本
Syntax语法
Changed in version 8.0.在版本8.0中的更改。
The command has the following syntax:该命令具有以下语法:
db.runCommand(
{
update: <collection>,
updates: [
{
q: <query>,
u: <document or pipeline>,
c: <document>, // Added in MongoDB 5.0
upsert: <boolean>,
multi: <boolean>,
collation: <document>,
arrayFilters: <array>,
hint: <document|string>,
sort: <document>
},
...
],
ordered: <boolean>,
maxTimeMS: <integer>,
writeConcern: { <write concern> },
bypassDocumentValidation: <boolean>,
comment: <any>,
let: <document> // Added in MongoDB 5.0
}
)Command Fields命令字段
The command takes the following fields:该命令包含以下字段:
update | ||
updates | ||
ordered | true, then when an update statement fails, return without performing the remaining update statements. true,则当更新语句失败时,返回而不执行其余的更新语句。false, then when an update fails, continue with the remaining update statements, if any. Defaults to true.false,则当更新失败时,继续执行剩余的更新语句(如果有的话)。默认为true。 | |
maxTimeMS |
| |
writeConcern |
| |
bypassDocumentValidation | update to bypass schema validation during the operation. This lets you update documents that do not meet the validation requirements.update以在操作期间绕过架构验证。这使您可以更新不符合验证要求的文档。 | |
comment |
| |
let |
| |
sort |
|
Update Statements更新语句
Each element of the updates array is an update statement document. Each document contains the following fields:updates数组的每个元素都是一个更新语句文档。每个文档包含以下字段:
q |
| |
u |
| |
c |
Note
| |
upsert |
| |
multi |
| |
collation |
| |
arrayFilters |
| |
hint |
|
Returns返回
The command returns a document that contains the status of the operation. For example:该命令返回一个包含操作状态的文档。例如:
{
"ok" : 1,
"nModified" : 0,
"n" : 1,
"upserted" : [
{
"index" : 0,
"_id" : ObjectId("52ccb2118908ccd753d65882")
}
]
}
For details of the output fields, see Output.有关输出字段的详细信息,请参阅输出。
Access Control访问控制
On deployments running with 在authorization, the user must have access that includes the following privileges:authorization运行的部署中,用户必须具有包括以下权限的访问权限:
指定集合上的updateaction on the specified collection(s).update操作。指定集合上的findaction on the specified collection(s).find操作。指定集合上的insertaction on the specified collection(s).insert操作。
The built-in role 内置角色readWrite provides the required privileges.readWrite提供了所需的权限。
Behavior行为
Limitations局限性
If you set 如果设置multi: true, use the update command only for idempotent operations.multi:true,则仅对幂等操作使用update命令。
Update with an Update Operator Expressions Document使用更新运算符表达式文档进行更新
The update statement field u can accept a document that only contains update operator expressions. For example:更新语句字段u可以接受仅包含更新运算符表达式的文档。例如:
updates: [
{
q: <query>,
u: { $set: { status: "D" }, $inc: { quantity: 2 } },
...
},
...
]
Then, the 然后,update command updates only the corresponding fields in the document.update命令仅更新文档中的相应字段。
Update with a Replacement Document使用替换文档进行更新
The update statement field u field can accept a replacement document, i.e. the document contains only 更新语句字段field:value expressions. For example:u字段可以接受替换文档,即文档仅包含field:value表达式。例如:
updates: [
{
q: <query>,
u: { status: "D", quantity: 4 },
...
},
...
]
Then the 然后,update command replaces the matching document with the update document. update命令将匹配的文档替换为更新文档。The update command can only replace a single matching document; i.e. the multi field cannot be true. update命令只能替换单个匹配的文档;即multi字段不能为true。The update command does not replace the _id value.update命令不会替换_id值。
Multi-Update Failures多次更新失败
If a single document fails to update in an update command with the 如果在multi parameter set to true, no further documents update as part of that command.multi参数设置为true的更新命令中,单个文档无法更新,则该命令中不会有其他文档更新。
For example, create a 例如,使用以下文档创建members collection with the following documents:members集合:
db.members.insertMany( [
{ "_id" : 1, "member" : "Taylor", "status" : "pending", "points" : 1},
{ "_id" : 2, "member" : "Alexis", "status" : "enrolled", "points" : 59},
{ "_id" : 3, "member" : "Elizabeth", "status" : "enrolled", "points" : 34}
] )
The following operation creates a document validator on the 以下操作使用members collection with a rule that the points value can not equal 60.points值不能等于60的规则在members集合上创建文档验证器。
db.runCommand( {
collMod: "members",
validator: { points: { $ne: 60 } }
} )
This update command increases the 此更新命令将每个文档的points field of every document by 1.points数字段增加1。
db.runCommand(
{
update: "members",
updates: [
{
q: {},
u: { $inc: { points: 1 } },
multi: true
}
]
}
)
After running the command, the collection contains the following documents:运行命令后,集合包含以下文档:
{ _id: 1, member: 'Taylor', status: 'A', points: 2 }
{ _id: 2, member: 'Alexis', status: 'D', points: 59 }
{ _id: 3, member: 'Elizabeth', status: 'C', points: 34 }
The update command updated the 更新命令更新了第一个文档的points value of the first document but failed to update the second document because of the validator rule that the points value can not equal 60. The third document did not update because no further documents update following a write error.points值,但由于验证器规则points值不能等于60,因此无法更新第二个文档。第三个文档没有更新,因为在写入错误后没有其他文档更新。
Note
If a subset of matched documents are updated, such as when an update would cause some documents to fail schema validation, the value of 如果更新了匹配文档的子集,例如更新会导致某些文档无法通过架构验证,则nModified returned by the update command might not be accurate.update命令返回的nModified值可能不准确。
Update with an Aggregation Pipeline使用聚合管道进行更新
The update statement field u field can accept an aggregation pipeline 更新语句字段[ <stage1>, <stage2>, ... ] that specifies the modifications to perform. The pipeline can consist of the following stages:u字段可以接受指定要执行的修改的聚合管道[ <stage1>, <stage2>, ... ]。该管道可以由以下阶段组成:
$addFieldsand its alias及其别名$set$projectand its alias及其别名$unset$replaceRootand its alias及其别名$replaceWith
Using the aggregation pipeline allows for a more expressive update statement, such as expressing conditional updates based on current field values or updating one field using the value of another field(s).使用聚合管道允许更具表现力的更新语句,例如基于当前字段值表示条件更新,或使用另一个字段的值更新一个字段。
For example:例如:
updates: [
{
q: <query>,
u: [
{ $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } },
{ $unset: [ "misc1", "misc2" ] }
],
...
},
...
]
Note
For examples, see Update with Aggregation Pipeline.有关示例,请参阅使用聚合管道进行更新。
Upsert with Unique Index使用唯一索引进行upsert
Upserts can create duplicate documents, unless there is a unique index to prevent duplicates.除非有唯一的索引来防止重复,否则Upsert可以创建重复的文档。
Consider an example where no document with the name 考虑一个例子,其中不存在名为Andy exists and multiple clients issue the following command at roughly the same time:Andy的文档,多个客户端大约同时发出以下命令:
db.runCommand(
{
update: "people",
updates: [
{ q: { name: "Andy" }, u: { $inc: { score: 1 } }, multi: true, upsert: true }
]
}
)
If all 如果所有update operations finish the query phase before any client successfully inserts data, and there is no unique index on the name field, each update operation may result in an insert, creating multiple documents with name: Andy.update操作都在任何客户端成功插入数据之前完成查询阶段,并且name字段上没有唯一索引,则每次update操作都可能导致插入,从而创建多个名为Andy的文档。
A unique index on the name field ensures that only one document is created. With a unique index in place, the multiple update operations now exhibit the following behavior:name字段上的唯一索引可确保只创建一个文档。有了唯一的索引,多个update操作现在表现出以下行为:
Exactly one只需一次updateoperation will successfully insert a new document.update操作,即可成功插入新文档。Other其他updateoperations either update the newly-inserted document or fail due to a unique key collision.update操作要么更新新插入的文档,要么由于唯一键冲突而失败。In order for other为了使其他updateoperations to update the newly-inserted document, all of the following conditions must be met:update操作更新新插入的文档,必须满足以下所有条件:The target collection has a unique index that would cause a duplicate key error.目标集合具有唯一索引,这将导致重复键错误。The update operation is not更新操作未updateManyormultiisfalse.updateMany或multi为false。The update match condition is either:更新匹配条件为:A single equality predicate. For example一个等式谓词。例如{ "fieldA" : "valueA" }A logical AND of equality predicates. For example等式谓词的逻辑AND。例如{ "fieldA" : "valueA", "fieldB" : "valueB" }
The fields in the equality predicate match the fields in the unique index key pattern.相等谓词中的字段与唯一索引键模式中的字段匹配。The update operation does not modify any fields in the unique index key pattern.更新操作不会修改唯一索引键模式中的任何字段。
The following table shows examples of 下表显示了当发生键冲突时,导致更新或失败的upsert operations that, when a key collision occurs, either result in an update or fail.upsert操作示例。
|
| score field of the matched document is incremented by 1.score字段递增1。 |
|
| name).name)中的字段。 |
|
| name, email) do not match the index key field (name).name、email)与索引键字段(name)不匹配。 |
Limits限制
For each update element in the 对于updates array, the sum of the query and the update sizes (i.e. q and u ) must be less than or equal to the maximum BSON document size.updates数组中的每个更新元素,查询和更新大小之和(即q和u)必须小于或等于BSON文档的最大大小。
The total number of update statements in the updates array must be less than or equal to the maximum bulk size.updates数组中的更新语句总数必须小于或等于最大批量大小。
Schema Validation模式验证
The >update命令添加了对update command adds support for the bypassDocumentValidation option, which lets you bypass schema validation when inserting or updating documents in a collection with validation rules.bypassDocumentValidation选项的支持,该选项允许您在使用验证规则在集合中插入或更新文档时绕过模式验证。
Sharded Collections分片化集合
upsert on a Sharded Collection分片集合上的upsert
upsert on a Sharded CollectionTo use 要在分片集合上使用update with multi: false on a sharded collection,multi:false更新,
If you do not specify upsert: true, the filter q must either include an equality match on the如果不指定_idfield or target a single shard (such as by including the shard key).upsert: true,则筛选器q必须在_id字段上包含相等匹配,或者以单个分片为目标(例如通过包含分片键)。If you specify upsert: true, the filter q must include an equality match on the shard key.如果指定upsert: true,则筛选器q必须在分片键上包含相等匹配。However, documents in a sharded collection can be missing the shard key fields.但是,分片集合中的文档可能会缺少分片键字段。To target a document that is missing the shard key, you can use the要针对缺少分片键的文档,您可以将nullequality match in conjunction with another filter condition (such as on the_idfield). For example:null相等匹配与另一个筛选条件结合使用(例如在_id字段上)。例如:{ _id: <value>, <shardkeyfield>: null } // _id of the document missing shard key
Replace Document替换文档
When replacing a document, 在替换文档时,update attempts to target a shard, first by using the query filter. update会尝试首先使用查询筛选器来定位一个分片。If the operation cannot target a single shard by the query filter, it then attempts to target by the replacement document.如果操作无法通过查询筛选器定位单个分片,则它会尝试通过替换文档定位。
Shard Key Modification分片键修改
You can update a document's shard key value unless the shard key field is the immutable 您可以更新文档的分片键值,除非分片键字段是不可变的_id field._id字段。
To modify the existing shard key value with 要使用update:update修改现有的分片键值,请执行以下操作:
You must run on a你必须在mongos. Do not issue the operation directly on the shard.mongos上运行。不要直接在分片上执行操作。You must run either in a transaction or as a retryable write.你必须在事务中运行或作为可重试写入运行。You must specify你必须指定multi: false.multi:false。You must include an equality query filter on the full shard key.您必须在完整分片键上包含一个相等查询筛选器。
Tip
Since a missing key value is returned as part of a null equality match, to avoid updating a null-valued key, include additional query conditions (such as on the 由于缺少的键值是作为空相等匹配的一部分返回的,为了避免更新空值键值,请酌情包含其他查询条件(例如在_id field) as appropriate._id字段上)。
See also 另请参阅分片系列的upsert on a Sharded Collection.upsert。
Missing Shard Key缺少分片键
Documents in a sharded collection can be missing the shard key fields. 分片集合中的文档可能缺少分片键字段。To use 要使用update to set the document's missing shard key, you must run on a mongos. Do not issue the operation directly on the shard.update设置文档缺少的分片键,你必须在mongos上运行。不要直接在分片上执行操作。
In addition, the following requirements also apply:此外,以下要求也适用:
nullnull |
|
null value:null值,请执行以下操作: |
|
Tip
Since a missing key value is returned as part of a null equality match, to avoid updating a null-valued key, include additional query conditions (such as on the 由于缺少的键值是作为空相等匹配的一部分返回的,为了避免更新空值键值,请酌情包含其他查询条件(例如在_id field) as appropriate._id字段上)。
See also:另请参阅:
Transactions事务
update can be used inside distributed transactions.可以在分布式事务中使用。
Important
In most cases, a distributed transaction incurs a greater performance cost over single document writes, and the availability of distributed transactions should not be a replacement for effective schema design. 在大多数情况下,分布式事务比单文档写入产生更大的性能成本,分布式事务的可用性不应取代有效的模式设计。For many scenarios, the denormalized data model (embedded documents and arrays) will continue to be optimal for your data and use cases. That is, for many scenarios, modeling your data appropriately will minimize the need for distributed transactions.对于许多场景,非规范化数据模型(嵌入式文档和数组)将继续是您的数据和用例的最佳选择。也就是说,对于许多场景,适当地对数据进行建模将最大限度地减少对分布式事务的需求。
For additional transactions usage considerations (such as runtime limit and oplog size limit), see also Production Considerations.有关其他事务使用注意事项(如运行时限制和oplog大小限制),另请参阅生产注意事项。
Upsert within Transactions事务中的失误
You can create collections and indexes inside a distributed transaction if the transaction is not a cross-shard write transaction.如果分布式事务不是跨分片写入事务,则可以在该事务内创建集合和索引。
update with 使用upsert: true can be run on an existing collection or a non-existing collection. If run on a non-existing collection, the operation creates the collection.upsert: true可以在现有集合或不存在的集合上运行。如果在不存在的集合上运行,则该操作将创建该集合。
Write Concerns and Transactions撰写入关注和事务
Do not explicitly set the write concern for the operation if run in a transaction. To use write concern with transactions, see Transactions and Write Concern.如果在事务中运行,则不要显式设置操作的写入关注。要对事务使用写关注,请参阅事务和写关注。
Examples示例
Update Specific Fields of One Document更新一个文档的特定字段
Use update operators to update only the specified fields of a document.使用更新运算符仅更新文档的指定字段。
For example, create a 例如,使用以下文档创建members collection with the following documents:members集合:
db.members.insertMany([
{ _id: 1, member: "abc123", status: "Pending", points: 0, misc1: "note to self: confirm status", misc2: "Need to activate" },
{ _id: 2, member: "xyz123", status: "D", points: 59, misc1: "reminder: ping me at 100pts", misc2: "Some random comment" },
])
The following command uses the 以下命令使用$set and $inc update operators to update the status and the points fields of a document where the member equals "abc123":$set和$inc更新运算符来更新文档的status和points字段,其中成员等于“abc123”:
db.runCommand(
{
update: "members",
updates: [
{
q: { member: "abc123" }, u: { $set: { status: "A" }, $inc: { points: 1 } }
}
],
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
Because 因为<update> document does not specify the optional multi field, the update only modifies one document, even if more than one document matches the q match condition.<update>文档没有指定可选的multi字段,所以即使有多个文档符合q匹配条件,更新也只会修改一个文档。
The returned document shows that the command found and updated a single document. The command returns:返回的文档显示该命令找到并更新了一个文档。命令返回:
{ "n" : 1, "nModified" : 1, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
After the command, the collection contains the following documents:命令后,集合包含以下文档:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" }
{ "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }Update Specific Fields of Multiple Documents更新多个文档的特定字段
Use update operators to update only the specified fields of a document, and include the 使用更新运算符仅更新文档的指定字段,并在更新语句中将multi field set to true in the update statement.multi字段设置为true。
For example, a 例如,members collection contains the following documents:members集合包含以下文档:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 1, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" }
{ "_id" : 2, "member" : "xyz123", "status" : "D", "points" : 59, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
The following command uses the 以下命令使用$set and $inc update operators to modify the status and the points fields respectively of all documents in the collection:$set和$inc更新运算符分别修改集合中所有文档的status字段和points字段:
db.runCommand(
{
update: "members",
updates: [
{ q: { }, u: { $set: { status: "A" }, $inc: { points: 1 } }, multi: true }
],
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
The update modifies all documents that match the query specified in the 更新将修改与q field, namely the empty query which matches all documents in the collection.q字段中指定的查询匹配的所有文档,即与集合中的所有文档匹配的空查询。
The returned document shows that the command found and updated multiple documents. For a replica set, the command returns:返回的文档显示该命令找到并更新了多个文档。对于副本集,该命令返回:
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
After the command, the collection contains the following documents:命令后,集合包含以下文档:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" }
{ "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }Update with Aggregation Pipeline使用聚合管道进行更新
The update command can use an aggregation pipeline for the update. The pipeline can consist of the following stages:update命令可以使用聚合管道进行更新。管道可包括以下阶段:
$addFieldsand its alias及其别名$set$projectand its alias及其别名$unset$replaceRootand its alias及其别名$replaceWith
Using the aggregation pipeline allows for a more expressive update statement, such as expressing conditional updates based on current field values or updating one field using the value of another field(s).使用聚合管道允许更具表现力的更新语句,例如基于当前字段值表示条件更新,或使用另一个字段的值更新一个字段。
Example示例 1
The following examples uses the aggregation pipeline to modify a field using the values of the other fields in the document.以下示例使用聚合管道使用文档中其他字段的值修改字段。
A members collection contains the following documents:members集合包含以下文档:
{ "_id" : 1, "member" : "abc123", "status" : "A", "points" : 2, "misc1" : "note to self: confirm status", "misc2" : "Need to activate" }
{ "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
Assume that instead of separate 假设您不想将misc1 and misc2 fields, you want to gather these into a new comments field. misc1和misc2字段分开,而是想将它们集合到一个新的comments字段中。The following update operation uses an aggregation pipeline to add the new 以下更新操作使用聚合管道添加新的comments field and remove the misc1 and misc2 fields for all documents in the collection.comments字段,并删除集合中所有文档的misc1和misc2字段。
First, set the首先,将statusfield to"Modified"and add a new fieldcommentsthat contains the current contents of two other fieldsmisc1andmisc2fields.status字段设置为"Modified",并添加一个新的字段comments,其中包含另外两个字段misc1和misc2字段的当前内容。Second, remove the其次,删除misc1andmisc2fields.misc1和misc2字段。
db.runCommand(
{
update: "members",
updates: [
{
q: { },
u: [
{ $set: { status: "Modified", comments: [ "$misc1", "$misc2" ] } },
{ $unset: [ "misc1", "misc2" ] }
],
multi: true
}
],
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
Note
The returned document shows that the command found and updated multiple documents. The command returns:返回的文档显示该命令找到并更新了多个文档。命令返回:
{ "n" : 2, "nModified" : 2, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
After the command, the collection contains the following documents:命令后,集合包含以下文档:
{ "_id" : 1, "member" : "abc123", "status" : "Modified", "points" : 2, "comments" : [ "note to self: confirm status", "Need to activate" ] }
{ "_id" : 2, "member" : "xyz123", "status" : "Modified", "points" : 60, "comments" : [ "reminder: ping me at 100pts", "Some random comment" ] }Example示例 2
The aggregation pipeline allows the update to perform conditional updates based on the current field values as well as use current field values to calculate a separate field value.聚合管道允许更新基于当前字段值执行条件更新,并使用当前字段值计算单独的字段值。
db.students.insertMany( [
{ "_id" : 1, "tests" : [ 95, 92, 90 ] },
{ "_id" : 2, "tests" : [ 94, 88, 90 ] },
{ "_id" : 3, "tests" : [ 70, 75, 82 ] }
] );
Using an aggregation pipeline, you can update the documents with the calculated grade average and letter grade.使用聚合管道,您可以使用计算出的平均成绩和字母成绩更新文档。
db.runCommand(
{
update: "students",
updates: [
{
q: { },
u: [
{ $set: { average : { $avg: "$tests" } } },
{ $set: { grade: { $switch: {
branches: [
{ case: { $gte: [ "$average", 90 ] }, then: "A" },
{ case: { $gte: [ "$average", 80 ] }, then: "B" },
{ case: { $gte: [ "$average", 70 ] }, then: "C" },
{ case: { $gte: [ "$average", 60 ] }, then: "D" }
],
default: "F"
} } } }
],
multi: true
}
],
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
Note
First Stage第一阶段The$setstage calculates a new fieldaveragebased on the average of thetestsfield. See$avgfor more information on the$avgaggregation operator.$set阶段根据tests字段的average值计算新的字段平均值。有关$avg聚合运算符的更多信息,请参阅$avg。Second Stage第二阶段The$setstage calculates a new fieldgradebased on theaveragefield calculated in the previous stage.$set阶段根据前一阶段计算的average字段计算新的字段grade。See有关$switchfor more information on the$switchaggregation operator.$switch聚合运算符的更多信息,请参阅$switch。
The returned document shows that the command found and updated multiple documents. The command returns:返回的文档显示该命令找到并更新了多个文档。命令返回:
{ "n" : 3, "nModified" : 3, "ok" : 1, <additional fields if run on a replica set/sharded cluster> }
After the command, the collection contains the following documents:命令后,集合包含以下文档:
{ "_id" : 1, "tests" : [ 95, 92, 90 ], "average" : 92.33333333333333, "grade" : "A" }
{ "_id" : 2, "tests" : [ 94, 88, 90 ], "average" : 90.66666666666667, "grade" : "A" }
{ "_id" : 3, "tests" : [ 70, 75, 82 ], "average" : 75.66666666666667, "grade" : "C" }Bulk Update批量更新
The following example performs multiple update operations on the 以下示例对members collection:members集合执行多个更新操作:
db.runCommand(
{
update: "members",
updates: [
{ q: { status: "P" }, u: { $set: { status: "D" } }, multi: true },
{ q: { _id: 5 }, u: { _id: 5, name: "abc123", status: "A" }, upsert: true }
],
ordered: false,
writeConcern: { w: "majority", wtimeout: 5000 }
}
)
The returned document shows that the command modified 返回的文档显示,该命令修改了10 documents and inserted a document with the _id value 5. See Output for details.10个文档,并插入了一个_id值为5的文档。详见输出。
{
"ok" : 1,
"nModified" : 10,
"n" : 11,
"upserted" : [
{
"index" : 1,
"_id" : 5
}
]
}Specify Collation指定排序规则
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:myColl集合有以下文件:
{ _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:以下操作包括collation选项:
db.runCommand({
update: "myColl",
updates: [
{ q: { category: "cafe", status: "a" }, u: { $set: { status: "Updated" } }, collation: { locale: "fr", strength: 1 } }
]
})Specify arrayFilters for Array Update Operations为数组更新操作指定arrayFilters
arrayFilters for Array Update OperationsWhen updating an array field, you can specify 更新数组字段时,可以指定arrayFilters来确定要更新的数组元素。arrayFilters that determine which array elements to update.
Update Elements Match arrayFilters Criteria更新元素匹配arrayFilters条件
arrayFilters CriteriaCreate a collection 使用以下文档创建students with the following documents:students集合:
db.students.insertMany( [
{ "_id" : 1, "grades" : [ 95, 92, 90 ] },
{ "_id" : 2, "grades" : [ 98, 100, 102 ] },
{ "_id" : 3, "grades" : [ 95, 110, 100 ] }
] );
To modify all elements that are greater than or equal to 要修改100 in the grades array, use the filtered positional operator $[<identifier>] with the arrayFilters option:grades数组中大于或等于100的所有元素,请使用带arrayFilters选项的筛选位置运算符$[<identifier>]:
db.runCommand( {
update: "students",
updates: [
{ q: { grades: { $gte: 100 } }, u: { $set: { "grades.$[element]" : 100 } }, arrayFilters: [ { "element": { $gte: 100 } } ], multi: true}
]
} )
After the operation, the collection contains the following documents:操作后,集合包含以下文档:
{ "_id" : 1, "grades" : [ 95, 92, 90 ] }
{ "_id" : 2, "grades" : [ 98, 100, 100 ] }
{ "_id" : 3, "grades" : [ 95, 100, 100 ] }Update Specific Elements of an Array of Documents更新文档数组的特定元素
Create a collection 使用以下文档创建集合students2 with the following documents:students2:
db.students2.insertMany( [
{
"_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 }
]
}
] )
To modify the value of the 要修改mean field for all elements in the grades array where the grade is greater than or equal to 85, use the filtered positional operator $[<identifier>] with the arrayFilters:grades数组中等级大于或等于85的所有元素的mean字段的值,请将筛选后的位置运算符$[<identifier>]与arrayFilters一起使用:
db.runCommand({
update: "students2",
updates: [
{ q: { }, u: { $set: { "grades.$[elem].mean" : 100 } }, arrayFilters: [ { "elem.grade": { $gte: 85 } } ], multi: true }
]
})
After the operation, the collection has the following documents:操作后,集合有以下文件:
{
"_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 }
]
}Specify hint for Update Operations指定更新操作的hint
hint for Update OperationsCreate a sample 使用以下文档创建示例members collection with the following documents:members集合:
db.members.insertMany([
{ "_id" : 1, "member" : "abc123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 2, "member" : "xyz123", "status" : "A", "points" : 60, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" },
{ "_id" : 3, "member" : "lmn123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 4, "member" : "pqr123", "status" : "D", "points" : 20, "misc1" : "Deactivated", "misc2" : null },
{ "_id" : 5, "member" : "ijk123", "status" : "P", "points" : 0, "misc1" : null, "misc2" : null },
{ "_id" : 6, "member" : "cde123", "status" : "A", "points" : 86, "misc1" : "reminder: ping me at 100pts", "misc2" : "Some random comment" }
])
Create the following indexes on the collection:在集合上创建以下索引:
db.members.createIndex( { status: 1 } )
db.members.createIndex( { points: 1 } )
The following update operation explicitly hints to use the index 以下更新操作明确提示使用索引{ status: 1 }:{ status: 1 }:
Note
If you specify an index that does not exist, the operation errors.如果指定的索引不存在,则操作会出错。
db.runCommand({
update: "members",
updates: [
{ q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true }
]
})
The update command returns the following:update命令返回以下内容:
{ "n" : 3, "nModified" : 3, "ok" : 1 }
To see the index used, run 要查看使用的索引,请在操作上运行explain on the operation:explain:
db.runCommand(
{
explain: {
update: "members",
updates: [
{ q: { "points": { $lte: 20 }, "status": "P" }, u: { $set: { "misc1": "Need to activate" } }, hint: { status: 1 }, multi: true }
]
},
verbosity: "queryPlanner"
}
)
Use Variables in let Option or c Field在let选项或c字段中使用变量
let Option or c FieldNew in version 5.0.在版本5.0中新增。
Variables can be defined in the let option or the c field and accessed in the 变量可以在updates array.let选项或c字段中定义,并在updates数组中访问。
Note
Create a collection 创建一个系列cakeFlavors:cakeFlavors:
db.cakeFlavors.insertMany( [
{ _id: 1, flavor: "chocolate" },
{ _id: 2, flavor: "strawberry" },
{ _id: 3, flavor: "cherry" }
] )
The following example defines 以下示例在targetFlavor and newFlavor variables in let and uses the variables to change the cake flavor from cherry to orange:let中定义了targetFlavor和newFlavor变量,并使用这些变量将蛋糕风味从樱桃味更改为橙色:
db.runCommand( {
update: db.cakeFlavors.getName(),
updates: [
{ q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
u: [ { $set: { flavor: "$$newFlavor" } } ] }
],
let : { targetFlavor: "cherry", newFlavor: "orange" }
} )
The next example defines 下一个例子在targetFlavor and newFlavor variables in c and uses the variables to change the cake flavor from chocolate to vanilla:c中定义了targetFlavor和newFlavor变量,并使用这些变量将蛋糕的味道从巧克力改为香草:
db.runCommand( {
update: db.cakeFlavors.getName(),
updates: [
{ q: { $expr: { $eq: [ "$flavor", "$$targetFlavor" ] } },
u: [ { $set: { flavor: "$$newFlavor" } } ],
c: { targetFlavor: "chocolate", newFlavor: "vanilla" } }
]
} )Output输出
The returned document contains a subset of the following fields:返回的文档包含以下字段的子集:
update.okThe status of the command.命令的状态。
update.nAnupdatecommand accepts an array of document updates, some of which can be upserts.update命令接受一系列文档更新,其中一些可能是upserts。For an update,对于更新,nis the number of documents selected for the update.n是为更新选择的文档数。For an upsert,对于upsert,插入的文档的nis1for the inserted document. The server adds thenvalues for all the updates and upserts and returns the total asupdate.n.n为1。服务器为所有更新和upsert添加n个值,并将总和作为update.n返回。If an update operation results in no change to the document, e.g.如果更新操作导致文档没有更改,例如$setexpression updates the value to the current value,ncan be greater thannModified.$set表达式将值更新为当前值,则n可以大于nModified。
update.nModifiedThe number of documents updated. If the update operation results in no change to the document, such as setting the value of the field to its current value,已更新的文档数量。如果更新操作不会导致文档发生更改,例如将字段的值设置为当前值,则nModifiedcan be less thann.nModified可以小于n。Note
If a subset of matched documents are updated, such as when an update would cause some documents to fail schema validation, the value of如果更新了匹配文档的子集,例如更新会导致某些文档无法通过架构验证,则nModifiedreturned by theupdatecommand might not be accurate.update命令返回的nModified值可能不准确。
update.upsertedAn array of documents that contains information for each document inserted through the update with一组文档,其中包含通过upsert: true.upsert:true更新插入的每个文档的信息。Each document contains the following information:每份文件包含以下信息:update.upserted.indexAn integer that identifies the update with一个整数,在upsert:truestatement in theupdatesarray, which uses a zero-based index.updates数组中使用upsert:true语句标识更新,该语句使用从零开始的索引。
update.upserted._idThe添加文档的_idvalue of the added document._id值。
update.writeErrorsAn array of documents that contains information regarding any error encountered during the update operation.一组文档,其中包含有关更新操作期间遇到的任何错误的信息。ThewriteErrorsarray contains an error document for each update statement that errors.writeErrors数组包含每个出错的更新语句的错误文档。Each error document contains the following fields:每个错误文档包含以下字段:update.writeErrors.indexAn integer that identifies the update statement in the一个整数,用于标识updatesarray, which uses a zero-based index.updates数组中的更新语句,该数组使用从零开始的索引。
update.writeErrors.codeAn integer value identifying the error.标识错误的整数值。
update.writeErrors.errmsgA description of the error.错误的描述。
update.writeConcernErrorDocument describing errors that relate to the write concern.描述与写入关注相关的错误的文档。Changed in version 7.0.6.在版本7.0.6中的更改。 (also available in 6.0.14 and 5.0.30也可在6.0.14和5.0.30中使用): When:当在updateexecutes onmongos, write concern errors are always reported, even when one or more write errors occur.mongos上执行update时,即使出现一个或多个写入错误,也总是会报告写入关注错误。In previous releases, the occurrence of write errors could cause the在以前的版本中,写入错误的发生可能会导致updateto not report write concern errors.update不报告写入关注错误。ThewriteConcernErrordocuments contain the following fields:writeConcernError文档包含以下字段:update.writeConcernError.codeAn integer value identifying the cause of the write concern error.一个整数值,用于标识写入关注错误的原因。
update.writeConcernError.errmsgA description of the cause of the write concern error.写入关注错误原因的描述。
update.writeConcernError.errInfo.writeConcernThe write concern object used for the corresponding operation. For information on write concern object fields, see Write Concern Specification.用于相应操作的写关注对象。有关写入关注对象字段的信息,请参阅写入关注规范。The write concern object may also contain the following field, indicating the source of the write concern:写入关注对象还可以包含以下字段,指示写入关注的来源:update.writeConcernError.errInfo.writeConcern.provenanceA string value indicating where the write concern originated (known as write concern一个字符串值,指示写关注的来源(称为写关注provenance). The following table shows the possible values for this field and their significance:provenance)。下表显示了此字段的可能值及其意义:Provenance来源Description描述clientSuppliedThe write concern was specified in the application.应用程序中指定了写入关注。customDefaultThe write concern originated from a custom defined default value. See写入关注源于自定义的默认值。请参阅setDefaultRWConcern.setDefaultRWConcern。getLastErrorDefaultsThe write concern originated from the replica set's写入关注源于副本集的settings.getLastErrorDefaultsfield.settings.getLastErrorDefaults字段。implicitDefaultThe write concern originated from the server in absence of all other write concern specifications.在没有所有其他写入关注规范的情况下,写入关注源自服务器。
Changed in version 8.1.2.在版本8.1.2中的更改。
When 当在分片集群中的update executes on mongos in a sharded cluster, a writeConcernError is always reported in the response, even when one or more other errors occur. mongos上执行update时,即使出现一个或多个其他错误,也总是在响应中报告writeConcernError。In previous releases, other errors sometimes caused 在以前的版本中,其他错误有时会导致update to not report write concern errors.update不报告写入关注错误。
For example, if a document fails validation, triggering a 例如,如果文档验证失败,触发DocumentValidationFailed error, and a write concern error also occurs, both the DocumentValidationFailed error and the writeConcernError are returned in the top-level field of the response.DocumentValidationFailed错误,并且还发生写入关注错误,则DocumentValidationFailure错误和writeConcernError都会在响应的顶级字段中返回。
In addition to the aforementioned update specific return fields, the 除了上述特定于更新的返回字段外,db.runCommand() includes additional information:db.runCommand()还包括其他信息:
for replica sets:对于副本集:optime,electionId,$clusterTime, andoperationTime.optime、electionId、$clusterTime和operationTime。for sharded clusters:对于分片集群:operationTimeand$clusterTime.operationTime和$clusterTime。
See db.runCommand Response for details on these fields.有关这些字段的详细信息,请参阅db.runCommand响应。
The following is an example document returned for a successful 以下是执行upsert的成功update command that performed an upsert:update命令返回的示例文档:
{
"ok" : 1,
"nModified" : 0,
"n" : 1,
"upserted" : [
{
"index" : 0,
"_id" : ObjectId("52ccb2118908ccd753d65882")
}
]
}
The following is an example document returned for a bulk update involving three update statements, where one update statement was successful and two other update statements encountered errors:以下是涉及三个更新语句的批量更新返回的示例文档,其中一个更新语句成功,另外两个更新语句遇到错误:
{
"ok" : 1,
"nModified" : 1,
"n" : 1,
"writeErrors" : [
{
"index" : 1,
"code" : 16837,
"errmsg" : "The _id field cannot be changed from {_id: 1.0} to {_id: 5.0}."
},
{
"index" : 2,
"code" : 16837,
"errmsg" : "The _id field cannot be changed from {_id: 2.0} to {_id: 6.0}."
},
]
}
Update Operation with a Sort使用排序更新操作
Create the following 创建以下restaurantsSort collection:restaurantsSort集合:
db.restaurantsSort.insertMany( [
{ _id: 1, name: "Pizza Place", rating: 4, violations: 2 },
{ _id: 2, name: "Burger Joint", rating: 3, violations: 5 },
{ _id: 3, name: "Taco Shop", rating: 4, violations: 1 }
] )
The following example replaces 以下示例将"Pizza Place" with "Clean Eats":"Pizza Place"替换为"Clean Eats":
db.runCommand( {
update: "restaurantsSort",
updates: [ {
// Find the restaurants with a rating of 4查找评级为4的餐厅
q: { rating: 4 },
// Replace the found restaurant with Clean Eats
u: { name: "Clean Eats", rating: 4, violations: 2 },
// Only update one restaurant仅更新一家餐厅
multi: false,
// Sort restaurants found by the most violations with a descending sort对违规次数最多的餐厅进行降序排序
sort: { violations: -1 }
} ]
} )
The example:示例:
Finds restaurants with a查找ratingof4, which are"Pizza Place"and"Taco Shop".rating为4的餐厅,分别是"Pizza Place"(披萨店)和"Taco Shop"(塔可店)。Sorts the found restaurants by按violationsin descending order, which places"Pizza Place"in the first position.violations(违规行为)降序排列找到的餐厅,将“Pizza Place”放在第一位。Replaces将"Pizza Place"with"Clean Eats"."Pizza Place"替换为"Clean Eats"。
The following query returns the restaurants:以下查询返回餐厅:
db.restaurantsSort.find()
Output shows 输出显示"Pizza Place" was replaced with "Clean Eats":"Pizza Place"被替换为"Clean Eats":
[
{ _id: 1, name: 'Clean Eats', rating: 4, violations: 2 },
{ _id: 2, name: 'Burger Joint', rating: 3, violations: 5 },
{ _id: 3, name: 'Taco Shop', rating: 4, violations: 1 }
]