对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。
Docs 菜单

批量写入操作

在本指南中,您可以学习;了解如何使用.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

指定操作是否绕过文档级验证。有关详细信息,请参阅 MongoDB Server 手册中的 模式验证
默认为 False

Comment

BsonValue 形式附加到操作的注释。有关更多信息,请参阅 MongoDB Server 手册中的“删除命令字段”指南。

IsOrdered

如果 True,则驱动程序会按照提供的顺序执行写入操作。如果发生错误,则不会尝试其他操作。

如果 False,驱动程序以任意顺序执行操作,并尝试执行所有操作。如果无序批量写入中的任何写入操作失败,驱动程序仅在尝试所有操作后报告错误。
默认为 True

Let

参数名称和值的映射,采用 BsonDocument 形式。 值必须是常量或不引用文档字段的闭合表达式。 有关更多信息,请参阅MongoDB Server手册中的 let声明。

以下代码示例使用 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

指示服务器是否确认了批量写入操作。如果此属性的值为 False,并且您尝试访问 BulkWriteResult 对象的任何其他属性,则驱动程序会抛出异常。

DeletedCount

删除的文档数量(如有)。

InsertedCount

插入的文档数量(如有)。

MatchedCount

更新匹配的文档数(如有)。

ModifiedCount

已修改文档的数量(如有)。

IsModifiedCountAvailable

指示修改后的计数是否可用。

Upserts

包含有关导致更新或插入(upsert)操作的每个请求的信息的列表。

RequestCount

批处理操作中的请求数。

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

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

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

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