Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs 菜单
Docs 主页
/ / /
C#/ .NET驱动程序
/ / /

批量写入操作

在本指南中,您可以学习;了解如何使用.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 以外的所有字段,并在 namecuisineboroughrestaurant_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

ArrayList 是实现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 类包含以下属性,它们表示可用于配置批量写入操作的选项:

属性
说明

BypassDocumentValidation

Specifies whether the operation bypasses document-level validation. For more information, see Schema Validation in the MongoDB Server manual.
Defaults to False.

Comment

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.

IsOrdered

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.

Let

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对象执行无序批量写入操作:

var models = new List<WriteModel<BsonDocument>>
{
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678")
)
};
var options = new BulkWriteOptions
{
IsOrdered = false,
};
collection.BulkWrite(models, options);
var models = new List<WriteModel<BsonDocument>>
{
new DeleteOneModel<BsonDocument>(
Builders<BsonDocument>.Filter.Eq("restaurant_id", "5678")
)
};
var options = new BulkWriteOptions
{
IsOrdered = false,
};
await collection.BulkWriteAsync(models, options);

BulkWrite()BulkWriteAsync() 方法返回包含以下属性的 BulkWriteResult对象:

属性
说明

IsAcknowledged

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.

DeletedCount

The number of documents deleted, if any.

InsertedCount

The number of documents inserted, if any.

MatchedCount

The number of documents matched for an update, if applicable.

ModifiedCount

The number of documents modified, if any.

IsModifiedCountAvailable

Indicates whether the modified count is available.

Upserts

A list that contains information about each request that resulted in an upsert operation.

RequestCount

The number of requests in the bulk operation.

如果批量写入操作中的任何操作失败, .NET/ C#驱动程序会抛出 BulkWriteError,并且不会执行任何进一步的操作。

BulkWriteError对象包含 Index属性,该属性描述导致错误的请求的索引。

要了解如何执行单个写入操作,请参阅以下指南:

要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档:

后退

删除

在此页面上