修改文档
在此页面上
Overview
在本指南中,您可以了解如何使用更新和替换操作修改 MongoDB 中的文档。
更新操作会更改您指定的字段,同时保持其他字段和值不变。替换操作会删除文档中除 _id
字段之外的所有现有字段,并用新字段和值替换已删除的字段。
本指南包括以下部分:
更新文档描述了如何使用驱动程序执行更新操作
替换文档描述了如何使用驾驶员执行替换操作
修改更新和替换行为描述了如何修改本指南中描述的方法的默认行为
附加信息提供了本指南中提到的类型和方法的资源和 API 文档链接
更新文档模式
在 MongoDB 中,所有更改文档的方法都遵循相同的模式:
注意
changeX()
是一个占位符,而不是一个真正的方法。
这些方法采用以下参数:
查询筛选器,用于匹配要更改的一个或多个文档
指定字段和值更改的更新文档
Rust 驱动程序提供以下方法来更改文档:
update_one()
update_many()
replace_one()
您可以使用复合操作在一个动作中检索和修改数据。 要学习;了解详情,请参阅复合操作指南。
_id 字段
MongoDB collection中的每个文档都有一个唯一且不可变的_id
字段。如果您尝试通过更新或替换操作更改_id
字段,驱动程序将引发WriteError
并且不会执行更新。
Update Documents
您可以通过以下方法执行更新操作:
update_one()
,更新匹配搜索条件的第一个文档update_many()
,这会更新所有符合搜索条件的文档
您还可以将选项构建器方法链接到这些更新操作方法。 要学习;了解如何修改更新方法的行为,请参阅本指南的“修改更新和替换行为”部分。
参数
每种方法都采用一个查询筛选器和一个包含至少一个更新操作符的更新文档。 更新操作符指定要执行的更新类型,并包括描述更改的字段和值。 更新文档使用以下格式:
doc! { "<update operator>": doc! { "<field>": <value> } }
要在一个更新文档中指定多个更新,请使用以下格式:
doc! { "<update operator>": doc!{"<field>": <value>}, "<update operator>": doc!{"<field>": <value>}, ... }
有关更新操作符和描述的完整列表,请参阅 MongoDB 服务器手册。
注意
更新操作中的聚合管道
如果您使用的是 MongoDB Server 4.2或更高版本,则可以在更新操作中使用聚合管道。 要了解有关 MongoDB 在聚合管道中支持的聚合阶段的更多信息,请参阅有关使用聚合管道执行更新的教程。
返回值
如果操作成功, update_one()
和update_many()
方法会返回UpdateResult
类型。 UpdateResult
类型包含以下描述操作的属性:
属性 | 说明 |
---|---|
| 过滤匹配的文档数 |
| 操作修改的文档数量 |
| 更新或插入文档的 |
如果多个文档与您传递给UpdateOne()
的查询筛选器匹配,则该方法会选择并更新第一个匹配的文档。 如果没有与查询筛选器匹配的文档,则更新操作不会进行更改。
更新示例
以下文档描述了公司的员工:
{ "_id": ObjectId('4337'), "name": "Shelley Olson", "department": "Marketing", "role": "Director", "bonus": 3000 }, { "_id": ObjectId('4902'), "name": "Remi Ibrahim", "department": "Marketing", "role": "Consultant", "bonus": 1800 }
此示例使用update_many()
方法执行更新操作。 update_many()
方法采用以下参数:
查询筛选器,用于匹配
department
字段的值为"Marketing"
的文档包含以下更新的更新文档:
$set
操作符,用于将department
的值更改为"Business Operations"
并将role
更改为"Analytics Specialist"
$inc
操作符,用于将bonus
的值增加500
let update_doc = doc! { "$set": doc! { "department": "Business Operations", "role": "Analytics Specialist" }, "$inc": doc! { "bonus": 500 } }; let res = my_coll .update_many(doc! { "department": "Marketing" }, update_doc) .await?; println!("Modified documents: {}", res.modified_count);
Modified documents: 2
以下文档反映了前面的更新操作所产生的更改:
{ "_id": ObjectId('4337'), "name": "Shelley Olson", "department": "Business Operations", "role": "Analytics Specialist", "bonus": 3500 }, { "_id": ObjectId('4902'), "name": "Remi Ibrahim", "department": "Business Operations", "role": "Analytics Specialist", "bonus": 2300 }
按 ObjectId 更新示例
以下文档描述了某公司的一名员工:
{ "_id": ObjectId('4274'), "name": "Jill Millerton", "department": "Marketing", "role": "Consultant" }
此示例通过指定查询筛选器以匹配文档的唯一_id
值来查询前一个文档。 然后,代码使用update_one()
方法执行更新操作。 update_one()
方法采用以下参数:
匹配
_id
字段值为ObjectId('4274')
的文档的查询筛选器更新创建将
name
的值设置为"Jill Gillison"
的指令的文档
let id = ObjectId::from_str("4274").expect("Could not convert to ObjectId"); let filter_doc = doc! { "_id": id }; let update_doc = doc! { "$set": doc! { "name": "Jill Gillison" } }; let res = my_coll .update_one(filter_doc, update_doc) .await?; println!("Modified documents: {}", res.modified_count);
Modified documents: 1
以下文档反映了上述更新操作导致的变更:
{ "_id": ObjectId('4274'), "name": "Jill Gillison", "department": "Marketing", "role": "Consultant" }
提示
要学习;了解有关_id
字段的更多信息,请参阅本页的_id字段部分或服务器手册中的ObjectId()方法文档。
替换文档
您可以使用replace_one()
方法执行替换操作。 此方法会将除_id
字段之外的文档所有现有字段替换为您指定的新字段和值。
您还可以将选项构建器方法链接到替换操作方法。 要学习;了解如何修改replace_one()
方法的行为,请参阅本指南的修改、更新和替换行为部分。
参数
replace_one()
方法采用查询筛选器和替换文档,其中包含将替换现有文档的字段和值。 替换文档使用以下格式:
doc! { "<field>": <value>, "<field>": <value>, ... }
Return Values
如果操作成功, replace_one
方法会返回UpdateResult
类型。 UpdateResult
类型包含以下描述操作的属性:
属性 | 说明 |
---|---|
| 过滤匹配的文档数 |
| 操作修改的文档数量 |
| 更新或插入文档的 |
如果多个文档与您传递给replace_one()
的查询筛选器匹配,则该方法会选择并替换第一个匹配的文档。 如果没有与查询筛选器匹配的文档,则替换操作不会进行任何更改。
替换示例
以下文档描述了某公司的一名员工:
{ "_id": ObjectId('4501'), "name": "Matt DeGuy", "role": "Consultant", "team_members": [ "Jill Gillison", "Susan Lee" ] }
此示例使用replace_one()
方法将前面的文档替换为具有以下字段的文档:
name
值为"Susan Lee"
role
值为"Lead Consultant"
team_members
值为[ "Jill Gillison" ]
let replace_doc = doc! { "name": "Susan Lee", "role": "Lead Consultant", "team_members": vec! [ "Jill Gillison" ] }; let res = my_coll .replace_one(doc! { "name": "Matt DeGuy" }, replace_doc) .await?; println!( "Matched documents: {}\nModified documents: {}", res.matched_count, res.modified_count );
Matched documents: 1 Modified documents: 1
被替换的文档包含替换文档的内容和不可变的_id
字段:
{ "_id": ObjectId('4501'), "name": "Susan Lee", "role": "Lead Consultant", "team_members": [ "Jill Gillison" ] }
修改更新和替换行为
您可以通过调用设立UpdateOptions
结构体字段的选项方法来修改update_one()
、 update_many
和replace_one()
方法的行为。
注意
设置选项
您可以通过将选项构建器方法直接链接到更新或替换方法调用来设立UpdateOptions
字段。 如果使用的是早期版本的驾驶员,则必须通过将选项构建器方法链接到builder()
方法来构造UpdateOptions
实例。 然后,将选项实例作为参数传递给update_one()
、 update_many
或replace_one()
。
下表描述了UpdateOptions
中可用的选项:
选项 | 说明 |
---|---|
| The set of filters specifying the array elements to which the
update applies. Type: Vec<Document> |
| If true , allows the driver to perform a write that violates
document-level validation. To learn more about validation, see
the guide on Schema Validation.Type: bool Default: false |
| If true, the operation inserts a document if no documents match
the query filter. Type: bool |
| The collation to use when sorting results. To learn more about collations,
see the Collations guide. Type: Collation Default: None |
| The index to use for the operation. This option is available
only when connecting to MongoDB Server versions 4.2 and later. Type: Hint Default: None |
| The write concern for the operation. If you don't set this
option, the operation inherits the write concern set for
the collection. To learn more about write concerns, see
Write Concern in the
Server manual. Type: WriteConcern |
| A map of parameters and values. These parameters can be accessed
as variables in aggregation expressions. This option is available
only when connecting to MongoDB Server versions 5.0 and later. Type: Document |
| An arbitrary Bson value tied to the operation to trace
it through the database profiler, currentOp , and
logs. This option is available only when connecting to
MongoDB Server versions 4.4 and later.Type: Bson Default: None |
以下代码展示了如何通过将upsert()
方法链接到update_one()
方法来设立upsert
字段:
let res = my_coll .update_one(filter_doc, update_doc) .upsert(true) .await?;
更多信息
有关本指南中概念的更多信息,请参阅以下文档:
有关更新和替换操作的可运行示例,请参阅以下用法示例:
要学习;了解有关更新操作符的更多信息,请参阅服务器手册中的更新操作符。
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: