批量写入操作
Overview
在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。
考虑这样一种情况:您想要将一个文档插入到一个集合中,更新多个其他文档,然后删除一个文档。 如果使用单独的方法,则每个操作都需要调用自己的数据库。 本指南向您介绍如何使用批量写入操作来减少对数据库的调用次数。
样本数据
本指南中的示例使用 Atlas示例数据集中的 sample_restaurants.restaurants
集合。 要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅入门教程。
重要
项目 Reactor 库
本指南使用 Project Reactor 库来使用Java Reactive Streams驾驶员方法返回的Publisher
实例。 要学习;了解有关 Project Reactor 库及其使用方法的更多信息,请参阅 入门 在 Reactor 文档中。要进一步学习;了解如何使用本指南中的 Project Reactor 库方法,请参阅“将数据写入MongoDB ”指南。
定义写入操作
对于要执行的每个写入操作,请创建以下类之一的实例:
InsertOneModel
UpdateOneModel
UpdateManyModel
ReplaceOneModel
DeleteOneModel
DeleteManyModel
然后,将这些实例的列表传递给bulkWrite()
方法。
以下部分介绍如何创建和使用上述类的实例。
插入操作
要执行插入操作,请创建InsertOneModel
的实例并传入要插入的文档。
以下示例创建了一个InsertOneModel
实例:
InsertOneModel<Document> operation = new InsertOneModel<>( new Document("name", "Mongo's Deli") .append("cuisine", "Sandwiches"));
要插入多个文档,请为每个文档创建一个InsertOneModel
实例。
更新操作
要更新文档,请创建UpdateOneModel
的实例并传入以下参数:
查询过滤,指定用于匹配集合中文档的条件。
要执行的更新操作。 有关更新操作的更多信息,请参阅MongoDB Server手册中的字段更新操作符指南。
UpdateOneModel
更新与查询筛选器匹配的第一个文档。
以下示例创建了一个UpdateOneModel
实例:
UpdateOneModel<Document> operation = new UpdateOneModel<>( eq("name", "Mongo's Deli"), set("cuisine", "Sandwiches and Salads"));
要更新多个文档,请创建UpdateManyModel
的实例并传入相同的参数。 UpdateManyModel
更新与查询过滤匹配的所有文档。
以下示例创建了一个UpdateManyModel
实例:
UpdateManyModel<Document> operation = new UpdateManyModel<>( eq("name", "Mongo's Deli"), set("cuisine", "Sandwiches and Salads"));
替换操作
替换操作会删除指定文档中除_id
字段之外的所有字段和值,并替换为新字段和值。 要执行替换操作,请创建ReplaceOneModel
的实例并传入查询过滤以及要存储在匹配文档中的字段和值。
以下示例创建了一个ReplaceOneModel
实例:
ReplaceOneModel<Document> operation = new ReplaceOneModel<>( eq("name", "Original Pizza"), new Document("name", "Mongo's Pizza") .append("borough", "Manhattan"));
要替换多个文档,请为每个文档创建一个ReplaceOneModel
实例。
删除操作
要删除文档,请创建DeleteOneModel
的实例并传入查询过滤,指定要删除的文档。 DeleteOneModel
仅删除与查询过滤匹配的第一个文档。
以下示例创建了一个DeleteOneModel
实例:
DeleteOneModel<Document> operation = new DeleteOneModel<>( eq("restaurant_id", "5678"));
要删除多个文档,请创建DeleteManyModel
的实例并传入查询过滤,指定要删除的文档。 DeleteManyModel
会删除与查询过滤匹配的所有文档。
以下示例创建了一个DeleteManyModel
实例:
DeleteManyModel<Document> operation = new DeleteManyModel<>( eq("name", "Mongo's Deli"));
调用bulkWrite()
方法
为要执行的每个操作定义类实例后,将这些实例的列表传递给bulkWrite()
方法。 默认,该方法按照列表中定义的顺序运行操作。
以下示例使用bulkWrite()
方法执行多个写入操作:
Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite( Arrays.asList(new InsertOneModel<>( new Document("name", "Mongo's Deli") .append("cuisine", "Sandwiches") .append("borough", "Manhattan") .append("restaurant_id", "1234")), new InsertOneModel<>(new Document("name", "Mongo's Deli") .append("cuisine", "Sandwiches") .append("borough", "Brooklyn") .append("restaurant_id", "5678")), new UpdateManyModel<>(eq("name", "Mongo's Deli"), set("cuisine", "Sandwiches and Salads")), new DeleteOneModel<>(eq("restaurant_id", "1234")))); BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block(); System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e0a6c08025218b657208}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e0a6c08025218b657209}}]}
如果任何写入操作失败, Java Reactive Streams驾驶员会发出MongoBulkWriteException
信号,并且不会执行任何进一步的单个操作。 MongoBulkWriteException
BulkWriteError
包括可使用 方法访问的MongoBulkWriteException.getWriteErrors()
,其中提供了单个故障的详细信息。
注意
当Java Reactive Streams驾驶员运行批量操作时,它会使用运行该操作的集合的writeConcern
。 无论执行顺序如何,驾驶员在尝试所有操作后都会报告所有写关注(write concern)错误。
自定义批量写入操作
BulkWriteOptions
类包含修改bulkWrite()
方法行为的方法。 要使用BulkWriteOptions
类,请构造该类的新实例,然后调用其一个或多个方法来修改写入操作。 您可以将这些方法调用链接在一起。 要修改写入操作的行为,请将类实例作为最后一个参数传递给bulkWrite()
方法。
您可以使用BulkWriteOptions
类中的以下方法来修改写入方法。 所有方法都是可选的。
方法 | 说明 |
---|---|
bypassDocumentValidation(Boolean bypassDocumentValidation) | Specifies whether the bulk write operation bypasses document validation. This lets you
perform write operations on documents that don't meet the schema validation requirements, if any
exist. For more information about schema validation, see Schema
Validation in the MongoDB
Server manual. |
comment(Bson comment) | Attaches a Bson comment to the operation. For more information, see the insert command
fields guide in the
MongoDB Server manual. |
comment(String comment) | Attaches a String comment to the operation. For more information, see the insert command
fields guide in the
MongoDB Server manual. |
let(Bson variables) | Specifies a map of parameter names and values. 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. |
ordered(Boolean ordered) | If set to True , the driver performs the individual operations in the order
provided. If an individual operation fails, the driver will not execute any
subsequent individual operations.Defaults to True . |
以下示例调用上一示例中的bulkWrite()
方法,但将ordered
选项设置为False
:
Publisher<BulkWriteResult> bulkWritePublisher = restaurants.bulkWrite( Arrays.asList(new InsertOneModel<>( new Document("name", "Mongo's Deli") .append("cuisine", "Sandwiches") .append("borough", "Manhattan") .append("restaurant_id", "1234")), new InsertOneModel<>(new Document("name", "Mongo's Deli") .append("cuisine", "Sandwiches") .append("borough", "Brooklyn") .append("restaurant_id", "5678")), new UpdateManyModel<>(eq("name", "Mongo's Deli"), set("cuisine", "Sandwiches and Salads")), new DeleteOneModel<>(eq("restaurant_id", "1234"))), new BulkWriteOptions().ordered(false)); BulkWriteResult bulkResult = Mono.from(bulkWritePublisher).block(); System.out.println(bulkResult.toString());
AcknowledgedBulkWriteResult{insertedCount=2, matchedCount=2, removedCount=1, modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0, id=BsonObjectId{value=66a7e03cce430c5854b6caf9}}, BulkWriteInsert{index=1, id=BsonObjectId{value=66a7e03cce430c5854b6cafa}}]}
如果无序批量写入中的任何写入操作失败, Java Reactive Streams驾驶员仅在尝试所有操作后才会报告错误。
注意
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: