修改文档
概述
在此指南中,您可以了解如何使用 MongoDB .NET/C# 驱动程序通过以下操作修改 MongoDB 集合中的文档:
.NET/C# 驱动程序提供了以下方法来修改文档,每个方法都有异步和同步版本:
UpdateOneAsync()
或UpdateOne()
UpdateManyAsync()
或UpdateMany()
ReplaceOneAsync()
或ReplaceOne()
提示
交互式实验室
此页面包含一个简短的交互式实验室,演示了如何使用 UpdateManyAsync()
方法修改数据。您可以直接在浏览器窗口中完成此实验室,无需安装 MongoDB 或代码编辑器。
要启动实验室,请单击打开交互式教程 按钮。要将实验室扩展到全屏格式,请单击实验室面板右上角的全屏按钮(⛶)。
示例数据
本指南中的示例使用 sample_restaurants
数据库中的 restaurants
集合。此集合中的文档使用以下 Restaurant
、Address
和 GradeEntry
类作为模型。
public class Restaurant { public ObjectId Id { get; set; } public string Name { get; set; } [ ] public string RestaurantId { get; set; } public string Cuisine { get; set; } public Address Address { get; set; } public string Borough { get; set; } public List<GradeEntry> Grades { get; set; } }
public class Address { public string Building { get; set; } [ ] public double[] Coordinates { get; set; } public string Street { get; set; } [ ] public string ZipCode { get; set; } }
public class GradeEntry { public DateTime Date { get; set; } public string Grade { get; set; } public float? Score { get; set; } }
注意
在“restaurants
”集合中,文档使用蛇形命名约定。本指南中的示例使用一个ConventionPack
将集合中的字段反序列化为帕斯卡命名法,并将它们映射到Restaurant
类中的属性。
要了解更多关于自定义序列化的信息,请参阅自定义序列化.
更新操作
您可以使用以下方法在MongoDB中执行更新操作
UpdateOne()
,它更新符合搜索条件的第一个文档UpdateMany()
,它更新所有符合搜索条件的文档
所需参数
每个更新方法都需要以下参数
一个查询过滤器文档,它确定要更新的记录。有关查询过滤器的更多信息,请参阅MongoDB服务器手册。
一个更新文档,它指定了更新操作符(要执行的类型更新)以及应更改的字段和值。有关更新操作符的完整列表及其用法,请参阅字段更新操作符手册页面。
.NET/C#驱动程序提供了一个Builders
类,该类简化了查询过滤器和更新文档的创建。以下代码示例使用Builders
创建两个文档,用于作为更新操作参数
一个查询过滤器,用于搜索具有“
cuisine
”字段值为“Pizza”的餐厅一个更新文档,将这些餐厅的“
cuisine
”字段值设置为“Pasta and breadsticks”
const string oldValue = "Pizza"; const string newValue = "Pasta and breadsticks"; // Creates a filter for all documents with a "cuisine" value of "Pizza" var filter = Builders<Restaurant>.Filter .Eq(restaurant => restaurant.Cuisine, oldValue); // Creates instructions to update the "cuisine" field of documents that // match the filter var update = Builders<Restaurant>.Update .Set(restaurant => restaurant.Cuisine, newValue); // Updates all documents that have a "cuisine" value of "Pizza" return _restaurantsCollection.UpdateMany(filter, update);
提示
更新操作中的聚合管道
如果您使用的是 MongoDB 版本 4.2 或更高版本,您可以在更新操作中使用由聚合阶段的子集组成的聚合管道。有关 MongoDB 在更新操作中支持的聚合阶段的更多信息,请参阅我们关于使用聚合管道进行更新的教程 使用聚合管道更新文档。
更新单个文档
以下代码展示了如何使用异步的 UpdateOneAsync()
方法或同步的 UpdateOne()
方法来更新单个文档。
var result = await _restaurantsCollection.UpdateOneAsync(filter, update);
var result = _restaurantsCollection.UpdateOne(filter, update);
更新多个文档
以下代码展示了如何使用异步的 UpdateManyAsync()
方法或同步的 UpdateMany()
方法来更新所有匹配的文档。
var result = await _restaurantsCollection.UpdateManyAsync(filter, update);
var result = _restaurantsCollection.UpdateMany(filter, update);
提示
在这些方法的可运行示例中,请参阅更多信息。
自定义更新操作
两种方法都可选地接受一个UpdateOptions
对象作为附加参数,该对象表示您可以使用它来配置更新操作。如果您没有指定任何UpdateOptions
属性,则驱动程序不会自定义更新操作。
UpdateOptions
类型允许您使用以下属性配置选项
属性 | 描述 |
---|---|
| 指定对数组字段进行更新操作时应修改哪些数组元素。有关更多信息,请参阅MongoDB服务器手册。 |
| 指定更新操作是否绕过文档验证。这允许您更新不满足模式验证要求的文档(如果存在)。有关模式验证的更多信息,请参阅MongoDB服务器手册。 |
| 指定排序结果时使用的语言排序规则类型。有关排序规则的更多信息,请参阅MongoDB服务器手册。 |
| 获取或设置操作的用户提供的注释。有关更多信息,请参阅MongoDB服务器手册。 |
| 获取或设置用于扫描文档的索引。有关更多信息,请参阅MongoDB服务器手册。 |
| 指定更新操作是否在查询过滤器没有匹配的文档时执行更新操作。有关更多信息,请参阅MongoDB服务器手册。 |
| 获取或设置let文档。有关更多信息,请参阅MongoDB服务器手册。 |
返回值
方法 UpdateOne()
和 UpdateMany()
每个都返回一个 UpdateResult
对象。类型 UpdateResult
包含以下属性
属性 | 描述 |
---|---|
| 指示 MongoDB 是否已确认更新操作。 |
| 指示是否可以在 UpdateResult 中读取已更新记录的计数。 |
| 匹配查询过滤器的文档数量,无论更新了多少。 |
| 更新操作更新的文档数量。如果更新的文档与原始文档相同,则不会包含在此计数中。 |
| 如果驱动程序执行了 upsert,则是在数据库中 upsert 的文档的 ID。 |
示例
以下代码使用 UpdateMany()
方法查找所有 borough
字段值为 "Manhattan" 的文档,然后将这些文档中的 borough
值更新为 "Manhattan (north)"。因为将 IsUpsert
选项设置为 true
,如果查询过滤器与任何现有文档不匹配,则驱动程序将插入一个新文档。
var filter = Builders<Restaurant>.Filter .Eq(restaurant => restaurant.Borough, "Manhattan"); var update = Builders<Restaurant>.Update .Set(restaurant => restaurant.Borough, "Manhattan (north)"); UpdateOptions opts = new UpdateOptions() { Comment = new BsonString("Borough updated for C# Driver Fundamentals"), IsUpsert = true }; Console.WriteLine("Updating documents..."); var result = _restaurantsCollection.UpdateMany(filter, update, opts); Console.WriteLine($"Updated documents: {result.ModifiedCount}"); Console.WriteLine($"Result acknowledged? {result.IsAcknowledged}");
Updating documents... Updated documents: 10259 Result acknowledged? True
注意
如果前面的示例使用的是 UpdateOne()
方法而不是 UpdateMany()
,则驱动程序将只更新匹配的文档中的第一个。
替换操作
您可以使用MongoDB中的ReplaceOne()
方法执行替换操作。此方法删除与搜索条件匹配的第一个文档的所有字段(除_id
字段外),然后将您指定的字段和值插入到文档中。
必需参数
ReplaceOne()
方法需要以下参数
查询过滤器文档,用于确定要替换的记录。
替换文档,指定要插入新文档中的字段和值。如果您的集合中的文档映射到一个C#类,则替换文档可以是此类的一个实例。
与更新操作类似,您可以在.NET/C#驱动程序中使用Builders
类创建查询过滤器。以下代码示例使用Builders
创建一个查询过滤器,用于搜索具有name
字段值为"Pizza Town"的餐厅。该代码还创建了一个新的Restaurant
对象,该对象将替换第一个匹配的文档。
// Creates a filter for all restaurant documents that have a "cuisine" value of "Pizza" var filter = Builders<Restaurant>.Filter .Eq(r => r.Cuisine, "Pizza"); // Finds the ID of the first restaurant document that matches the filter var oldPizzaRestaurant = _restaurantsCollection.Find(filter).First(); var oldId = oldPizzaRestaurant.Id; // Generates a new restaurant document Restaurant newPizzaRestaurant = new() { Id = oldId, Name = "Mongo's Pizza", Cuisine = "Pizza", Address = new() { Street = "Pizza St", ZipCode = "10003" }, Borough = "Manhattan", }; // Replaces the existing restaurant document with the new document return _restaurantsCollection.ReplaceOne(filter, newPizzaRestaurant);
重要
_id
字段的值不可变。如果您的替换文档指定了_id
字段的值,它必须与现有文档的_id
值匹配。
以下代码演示了如何使用异步的ReplaceOneAsync()
方法或同步的ReplaceOne()
方法替换一个文档。
var result = await _restaurantsCollection.ReplaceOneAsync(filter, newRestaurant);
var result = _restaurantsCollection.ReplaceOne(filter, newRestaurant);
提示
在这些方法的可运行示例中,请参阅更多信息。
自定义替换操作
ReplaceOne()
方法可选地接受一个 ReplaceOptions
对象作为附加参数,该对象表示可以用来配置替换操作的选项。如果您不指定任何 ReplaceOptions
属性,则驱动程序不会自定义替换操作。
ReplaceOptions
类型允许您使用以下属性来配置选项
属性 | 描述 |
---|---|
| 指定替换操作是否绕过文档验证。这允许您替换不符合模式验证要求的文档(如果存在)。有关模式验证的更多信息,请参阅 MongoDB 服务器手册。 |
| 指定排序结果时使用的语言排序规则类型。有关排序规则的更多信息,请参阅MongoDB服务器手册。 |
| 获取或设置操作的用户提供的注释。有关更多信息,请参阅MongoDB服务器手册。 |
| 获取或设置用于扫描文档的索引。有关更多信息,请参阅MongoDB服务器手册。 |
| 指定如果查询过滤器没有匹配的文档,则替换操作是否执行更新操作。有关更多信息,请参阅 MongoDB 服务器手册。 |
| 获取或设置let文档。有关更多信息,请参阅MongoDB服务器手册。 |
返回值
ReplaceOne()
方法返回一个 ReplaceOneResult
对象。该 ReplaceOneResult
类型包含以下属性
属性 | 描述 |
---|---|
| 指示替换操作是否被 MongoDB 确认。 |
| 指示您是否可以读取 ReplaceOneResult 上的替换记录数。 |
| 匹配查询过滤器的文档数,无论是否有一个被替换。 |
| 替换操作替换的文档数。 |
| 如果驱动程序执行了 upsert,则是在数据库中 upsert 的文档的 ID。 |
示例
以下代码使用ReplaceOne()
方法查找第一个name
字段值为"Pizza Town"的文档,然后将其替换为一个新的名为"Food World"的Restaurant
文档。由于将IsUpsert
选项设置为true
,如果查询过滤器与任何现有文档不匹配,则驱动程序将插入一个新的文档。
var filter = Builders<Restaurant>.Filter.Eq(restaurant => restaurant.Name, "Pizza Town"); Restaurant newRestaurant = new() { Name = "Food World", Cuisine = "American", Address = new BsonDocument { {"street", "Food St"}, {"zipcode", "10003"}, }, Borough = "Manhattan", }; ReplaceOptions opts = new ReplaceOptions() { Comment = new BsonString("Restaurant replaced for .NET/C# Driver Fundamentals"), IsUpsert = true }; Console.WriteLine("Replacing document..."); var result = _restaurantsCollection.ReplaceOne(filter, newRestaurant, opts); Console.WriteLine($"Replaced documents: {result.ModifiedCount}"); Console.WriteLine($"Result acknowledged? {result.IsAcknowledged}");
Replacing document... Replaced documents: 1 Result acknowledged? True
附加信息
有关更新和替换操作的运行示例,请参阅以下使用示例
要了解更多关于创建查询筛选器的信息,请参阅指定查询指南。
API 文档
要了解更多关于本指南中讨论的任何方法或类型的信息,请参阅以下API文档