Overview
在本指南中,您可以学习;了解如何使用.NET/ C#驱动程序执行批量写入操作。通过使用批量写入操作,您可以通过更少的数据库调用来执行多个写入操作。
考虑需要为同一任务插入文档、更新文档和删除文档的情况。 如果使用单独的写入方法执行每种类型的操作,则每次写入都会单独访问数据库。 您可以使用批量写入操作来优化应用程序对服务器的调用次数。
您可以使用 IMongoCollection.BulkWrite()
或 IMongoCollection.BulkWriteAsync()
方法对单个集合执行批量写入操作。每个方法都有一个 WriteModel<TDocument>
实例列表,这些实例描述要执行的写入操作。
样本数据
本指南中的示例使用sample_restaurants.restaurants
Atlas示例数据集中的 集合。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅 快速入门教程。
定义写入操作
对于要执行的每个写入操作,请创建以下 WriteModel<TDocument>
类之一的实例:
DeleteManyModel<TDocument>
DeleteOneModel<TDocument>
InsertOneModel<TDocument>
ReplaceOneModel<TDocument>
UpdateManyModel<TDocument>
UpdateOneModel<TDocument>
以下部分介绍如何创建并使用上述类的实例,以在批量写入操作中执行相应的写入操作。
提示
使用 POCO 进行批量写入操作
本指南中的示例在所有泛型类中使用 BsonDocument
类型作为 TDocument
类型。您还可以对这些类使用普通旧 CLR 对象 (POCO)。 为此,必须定义一个类来表示集合中的文档。 该类必须具有与文档中的字段匹配的属性。 有关更多信息,请参阅 POCO。
插入操作
要执行插入操作,请创建一个InsertOneModel<TDocument>
实例并指定要插入的文档。
以下示例创建了 InsertOneModel<BsonDocument>
类的实例。此实例指示驾驶员将 "name"
字段为 "Mongo's Deli"
的文档插入到 restaurants
集合中。
var insertOneModel = new InsertOneModel<BsonDocument>( new BsonDocument{ { "name", "Mongo's Deli" }, { "cuisine", "Sandwiches" }, { "borough", "Manhattan" }, { "restaurant_id", "1234" } } );
要插入多个文档,请为每个文档创建一个InsertOneModel<TDocument>
实例。
重要
重复键错误
执行批量操作时, InsertOneModel<TDocument>
无法插入集合中已存在的具有_id
的文档。 在这种情况下,驾驶员会抛出MongoBulkWriteException
。
更新操作
要更新单个文档,请创建 UpdateOneModel<TDocument>
的实例并传递以下参数:
查询过滤,指定用于匹配集合中文档的条件。要学习;了解有关指定查询的更多信息,请参阅MongoDB Server手册中的查询和投影操作符。
描述要执行的更新的更新文档。要学习;了解有关指定更新的更多信息,请参阅MongoDB Server手册中的 Update Operators。
UpdateOneModel<TDocument>
实例指定与查询过滤匹配的第一个文档的更新。
在以下代码示例中,UpdateOneModel<BsonDocument>
对象表示 restaurants
集合上的更新操作。该操作匹配集合中 name
字段的值为 "Mongo's Deli"
的第一个文档。然后,它将匹配文档中 cuisine
字段的值更新为 "Sandwiches and Salads"
。
var updateOneModel = new UpdateOneModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"), Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads") );
要更新多个文档,请创建UpdateManyModel<TDocument>
的实例并传递与UpdateOneModel<TDocument>
相同的参数。 UpdateManyModel<TDocument>
类指定与查询过滤匹配的所有文档的更新。
在以下代码示例中,UpdateManyModel<BsonDocument>
对象表示 restaurants
集合上的更新操作。该操作匹配集合中 name
字段的值为 "Mongo's Deli"
的所有文档。然后,它将 cuisine
字段的值更新为 "Sandwiches and Salads"
。
var updateManyModel = new UpdateManyModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"), Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads") );
替换操作
替换操作会删除指定文档的所有字段和值,并将其替换为您指定的新字段和值。 要执行替换操作,请创建ReplaceOneModel<TDocument>
实例并传递查询过滤以及要用于替换匹配文档的字段和值。
在以下示例中,ReplaceOneModel<BsonDocument>
对象表示 restaurants
集合上的替换操作。该操作匹配集合中 restaurant_id
字段值为 "1234"
的文档。然后,它会从此文档中删除 _id
以外的所有字段,并在 name
、cuisine
、borough
和 restaurant_id
字段中设置新值。
var replaceOneModel = new ReplaceOneModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234"), new BsonDocument{ { "name", "Mongo's Pizza" }, { "cuisine", "Pizza" }, { "borough", "Brooklyn" }, { "restaurant_id", "5678" } } );
要替换多个文档,必须为每个文档创建一个ReplaceOneModel<TDocument>
实例。
删除操作
要删除文档,请创建DeleteOneModel<TDocument>
的实例并传递查询过滤,指定要删除的文档。 DeleteOneModel<TDocument>
实例提供了仅删除与查询过滤匹配的第一个文档的说明。
在以下代码示例中,DeleteOneModel<BsonDocument>
对象表示 restaurants
集合上的删除操作。该操作匹配并删除 restaurant_id
字段的值为 "5678"
的第一个文档。
var deleteOneModel = new DeleteOneModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678") );
要删除多个文档,请创建 DeleteManyModel<TDocument>
的实例并传递查询过滤,指定要删除的文档。DeleteManyModel<TDocument>
的实例提供了删除与查询过滤匹配的所有文档的说明。
在以下代码示例中,DeleteManyModel<BsonDocument>
对象表示 restaurants
集合上的删除操作。该操作会匹配并删除 name
字段的值为 "Mongo's Deli"
的所有文档。
var deleteManyModel = new DeleteManyModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli") );
执行批量操作
为要执行的每个操作定义 WriteModel
实例后,创建一个实现 IEnumerable
接口的类的实例。将您的 WriteModel
对象添加到此 IEnumerable
,然后将 IEnumerable
传递给 BulkWrite()
或 BulkWriteAsync()
方法。默认下,这些方法按照列表中定义的顺序运行操作。
提示
IEnumerable
Array
和 List
是实现IEnumerable
接口的两个常用类。
从以下标签页中进行选择,查看如何使用同步 BulkWrite()
方法和异步 BulkWriteAsync()
方法对 restaurants
集合执行批量写入操作:
var models = new List<WriteModel<BsonDocument>> { new InsertOneModel<BsonDocument>( new BsonDocument{ { "name", "Mongo's Deli" }, { "cuisine", "Sandwiches" }, { "borough", "Manhattan" }, { "restaurant_id", "1234" } } ), new InsertOneModel<BsonDocument>( new BsonDocument{ { "name", "Mongo's Deli" }, { "cuisine", "Sandwiches" }, { "borough", "Brooklyn" }, { "restaurant_id", "5678" } } ), new UpdateManyModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"), Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads") ), new DeleteOneModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234") ) }; var results = collection.BulkWrite(models); Console.WriteLine(results);
var models = new List<WriteModel<BsonDocument>> { new InsertOneModel<BsonDocument>( new BsonDocument{ { "name", "Mongo's Deli" }, { "cuisine", "Sandwiches" }, { "borough", "Manhattan" }, { "restaurant_id", "1234" } } ), new InsertOneModel<BsonDocument>( new BsonDocument{ { "name", "Mongo's Deli" }, { "cuisine", "Sandwiches" }, { "borough", "Brooklyn" }, { "restaurant_id", "5678" } } ), new UpdateManyModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("name", "Mongo's Deli"), Builders<BsonDocument>.Update.Set("cuisine", "Sandwiches and Salads") ), new DeleteOneModel<BsonDocument>( Builders<BsonDocument>.Filter.Eq("restaurant_id", "1234") ) }; var results = await collection.BulkWriteAsync(models); Console.WriteLine(results);
前面的代码示例生成以下输出:
MongoDB.Driver.BulkWriteResult1+Acknowledged[MongoDB.Bson.BsonDocument]
注意
当驾驶员运行批量操作时,它会使用目标集合的写关注(write concern)。 无论执行顺序如何,驾驶员在尝试所有操作后都会报告所有写关注(write concern)错误。
自定义批量写入操作
调用 BulkWrite()
或 BulkWriteAsync()
方法时,可以传递 BulkWriteOptions
类的实例。BulkWriteOptions
类包含以下属性,它们表示可用于配置批量写入操作的选项:
属性 | 说明 |
---|---|
| Specifies whether the operation bypasses document-level validation. For more
information, see Schema
Validation in the MongoDB Server
manual. Defaults to False . |
| A comment to attach to the operation, in the form of a BsonValue . For
more information, see the delete command
fields guide in the
MongoDB Server manual. |
| If True , the driver performs the write operations in the order
provided. If an error occurs, the remaining operations are not
attempted.If False , the driver performs the operations in an
arbitrary order and attempts to perform all operations. If any of the write
operations in an unordered bulk write fail, the driver
reports the errors only after attempting all operations.Defaults to True . |
| A map of parameter names and values, in the form of a BsonDocument . Values
must be constant or closed
expressions that don't reference document fields. For more information,
see the let statement in the
MongoDB Server manual. |
以下代码示例使用 BulkWriteOptions
对象执行无序批量写入操作:
返回值
BulkWrite()
和 BulkWriteAsync()
方法返回包含以下属性的 BulkWriteResult
对象:
属性 | 说明 |
---|---|
| Indicates whether the server acknowledged the bulk write operation. If the
value of this property is False and you try to access any other property
of the BulkWriteResult object, the driver throws an exception. |
| The number of documents deleted, if any. |
| The number of documents inserted, if any. |
| The number of documents matched for an update, if applicable. |
| The number of documents modified, if any. |
| Indicates whether the modified count is available. |
| A list that contains information about each request that
resulted in an upsert operation. |
| The number of requests in the bulk operation. |
处理异常
如果批量写入操作中的任何操作失败, .NET/ C#驱动程序会抛出 BulkWriteError
,并且不会执行任何进一步的操作。
BulkWriteError
对象包含 Index
属性,该属性描述导致错误的请求的索引。
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: