修改文档
概述
在本指南中,您可以了解如何使用更新和替换操作修改 MongoDB 中的文档。
更新操作会更改您指定的字段,同时保持其他字段和值不变。替换操作会删除文档中除 _id
字段之外的所有现有字段,并用新字段和值替换已删除的字段。
本指南包括以下部分:
更新文档描述了如何使用驱动程序执行更新操作
替换文档描述了如何使用驱动程序执行替换操作
修改更新和替换行为描述了如何修改本指南中描述的方法的默认行为
其他信息提供了指向本指南中提及的类型和方法的资源和 API 文档的链接
更新文档模式
在 MongoDB 中,所有更改文档的方法都遵循相同的模式:
注意
changeX()
是占位符,而不是真正的方法。
这些方法采用以下参数:
查询筛选器,用于匹配要更改的一个或多个文档
指定字段和值更改的更新文档
(可选)用于修改方法默认行为的选项类型
Rust 驱动程序提供以下方法来更改文档:
update_one()
update_many()
replace_one()
您可以使用复合操作在一个操作中检索和修改数据。要了解更多信息,请参阅复合操作指南。
_id 字段
MongoDB collection中的每个文档都有一个唯一且不可变的_id
字段。如果您尝试通过更新或替换操作更改_id
字段,驱动程序将引发WriteError
并且不会执行更新。
更新文档
您可以通过以下方法执行更新操作:
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 在聚合管道中支持的聚合阶段的更多信息,请参阅有关使用聚合管道执行更新的教程。
更新操作还采用UpdateOptions
参数。 要了解如何修改更新方法的行为,请参阅本指南的修改更新和替换行为部分。
返回值
如果操作成功, update_one()
和update_many()
方法会返回UpdateResult
类型。 UpdateResult
类型包含以下描述操作的属性:
属性 | 说明 |
---|---|
matched_count | 筛选器匹配的文档数 |
modified_count | 该操作修改的文档数 |
upserted_id | 更新或插入文档的 _id ,如果没有则为空 |
如果多个文档与您传递给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, None) .await?; println!("Modified documents: {}", res.modified_count);
以下文档反映了前面的更新操作所产生的更改:
{ "_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, None) .await?; println!("Modified documents: {}", res.modified_count);
以下文档反映了上述更新操作导致的变更:
{ "_id": ObjectId('4274'), "name": "Jill Gillison", "department": "Marketing", "role": "Consultant" }
提示
要了解有关_id
字段的更多信息,请参阅本页的_id 字段部分或服务器手册中的ObjectId()方法文档。
替换文档
您可以使用replace_one()
方法执行替换操作。 此方法会将除_id
字段之外的文档所有现有字段替换为您指定的新字段和值。
参数
replace_one()
方法采用查询筛选器和替换文档,其中包含将替换现有文档的字段和值。 替换文档使用以下格式:
doc! { "<field>": <value>, "<field>": <value>, ... }
替换操作还采用UpdateOptions
参数。要了解如何修改replace_one()
方法的行为,请参阅本指南的修改更新和替换行为部分。
返回值
如果操作成功, replace_one
方法会返回UpdateResult
类型。 UpdateResult
类型包含以下描述操作的属性:
属性 | 说明 |
---|---|
matched_count | 筛选器匹配的文档数 |
modified_count | 该操作修改的文档数 |
upserted_id | 更新或插入文档的 _id ,如果没有则为空 |
如果多个文档与您传递给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, None) .await?; println!( "Matched documents: {}\nModified documents: {}", res.matched_count, res.modified_count );
被替换的文档包含替换文档的内容和不可变的_id
字段:
{ "_id": ObjectId('4501'), "name": "Susan Lee", "role": "Lead Consultant", "team_members": [ "Jill Gillison" ] }
修改更新和替换行为
您可以通过构造UpdateOptions
结构并将其作为参数传递来修改update_one()
、 update_many
和replace_one()
方法的行为。
注意
实例化选项
Rust 驱动程序实现了用于创建许多不同类型的 Builder 设计模式,包括UpdateOptions
。 您可以使用每种类型的builder()
方法,通过逐个链接选项构建器函数来构造选项实例。
下表描述了UpdateOptions
中可用的选项:
选项 | 说明 |
---|---|
array_filters | 指定要应用更新的数组元素的筛选器集。 类型: Vec<Document> |
bypass_document_validation | |
upsert | 如果为 true,则在没有与查询筛选器匹配的文档时,该操作会插入一个文档。 类型: bool |
collation | |
hint | 用于操作的索引。 此选项仅在连接到 MongoDB Server 4.2 及更高版本时可用。 类型: Hint 默认: None |
write_concern | |
let_vars | 参数和值的映射。 这些参数可以作为聚合表达式中的变量进行访问。 此选项仅在连接到 MongoDB Server 5.0 及更高版本时可用。 类型: Document |
comment | 与操作绑定的任意 Bson 值,以通过数据库分析器、 currentOp 和日志进行跟踪。 此选项仅在连接到 MongoDB Server 4.4 及更高版本时可用。类型: Bson 默认: None |
以下代码展示了如何构造UpdateOptions
实例并将其传递给update_one()
方法:
let opts: UpdateOptions = UpdateOptions::builder().upsert(true).build(); let res = my_coll.update_one(filter_doc, update_doc, opts).await?;
更多信息
有关本指南中概念的更多信息,请参阅以下文档:
有关更新和替换操作的可运行示例,请参阅以下用法示例:
要了解有关更新操作符的更多信息,请参阅服务器手册中的更新操作符。
API 文档
要进一步了解本指南所提及的方法和类型,请参阅以下 API 文档: