批量写入操作
Overview
在本指南中,您可以学习;了解如何使用批量写入操作在单个数据库调用中执行多个写入操作。
考虑这样一个场景:您要插入一个文档,更新多个其他文档,然后删除一个文档。 如果使用单独的方法,则每个操作都需要调用自己的数据库。
通过使用批量写入操作,您可以通过更少的数据库调用来执行多个写入操作。 您可以在以下级别执行批量写入操作:
客户端:如果您的应用程序连接到MongoDB Server 8.0 或更高版本,则可以使用
MongoDB\Client::bulkWrite()
方法对同一集群中的多个集合和数据库执行批量写入操作。此方法在一次数据库调用中执行所有写入操作。要学习;了解有关此功能的更多信息,请参阅 Mongo.bulkWrite()MongoDB Server手册中的参考文档。集合:您可以使用
MongoDB\Collection::bulkWrite()
方法对单个集合执行批量写入操作。此方法对每种类型的写入操作进行一次数据库调用。示例,该方法可以在一次调用中执行多个更新操作,但会两次单独调用数据库以执行插入操作和替换操作。
样本数据
本指南中的示例使用Atlas示例数据集中的sample_restaurants.restaurants
和sample_mflix.movies
集合。要学习;了解如何创建免费的MongoDB Atlas 群集并加载示例数据集,请参阅Atlas入门指南。
客户端批量写入
使用PHP库 v2.1 并连接到运行MongoDB Server 8.0 或更高版本的部署时,可以使用 MongoDB\Client::bulkWrite()
方法写入同一集群中的多个数据库和集合。此方法在一次调用中执行所有写入操作。
首先,使用 MongoDB\ClientBulkWrite
构建器创建BulkWriteCommand实例,以指定要执行的写入操作。以下代码演示了如何使用 createWithCollection()
方法从 MongoDB\Collection
实例创建 ClientBulkWrite
实例:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection);
然后,在 ClientBulkWrite
实例上调用以下一个或多个写入方法以构造批量写入操作:
deleteOne()
deleteMany()
insertOne()
replaceOne()
updateOne()
updateMany()
要为后续写入操作选择不同的命名空间,请对 ClientBulkWrite
实例调用 withCollection()
方法,如以下代码所示:
$movieCollection = $client->sample_mflix->movies; $bulkWrite = $bulkWrite->withCollection($movieCollection);
以下部分介绍如何创建和使用 ClientBulkWrite
类来指定批量写入中的写入操作。执行批量操作部分演示了如何将 ClientBulkWrite
对象传递给 bulkWrite()
方法以执行批量操作。
插入操作
要指定插入操作,请在 ClientBulkWrite
实例上调用 insertOne()
方法。
以下示例指定将文档插入到 sample_restaurants.restaurants
和 sample_mflix.movies
集合中:
$restaurantCollection = $client->sample_restaurants->restaurants; $movieCollection = $client->sample_mflix->movies; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->insertOne(['name' => 'Mongo Deli', 'cuisine' => 'Sandwiches']); $bulkWrite = $bulkWrite->withCollection($movieCollection); $bulkWrite->insertOne(['title' => 'The Green Ray', 'year' => 1986]);
更新操作
要指定对第一个匹配文档执行更新操作,请对 ClientBulkWrite
实例调用 updateOne()
方法。
以下示例指定对 sample_restaurants.restaurants
集合中 name
值为 'Dandelion Bakery'
的第一个文档进行 $set
更新:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->updateOne( ['name' => 'Dandelion Bakery'], ['$set' => ['grade' => 'B+']], ['upsert' => true], );
要更新多个文档,请调用 updateMany()
方法。指定的操作会更新与查询过滤匹配的所有文档。
以下示例指定对 sample_restaurants.restaurants
集合中 name
值为 'Starbucks'
的所有匹配文档进行 $set
更新:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->updateMany( ['name' => 'Starbucks'], ['$set' => ['cuisine' => 'Coffee (Chain)']], );
替换操作
要指定对第一个匹配文档执行替换操作,请对 ClientBulkWrite
实例调用 replaceOne()
方法。
以下示例指定对 sample_restaurants.restaurants
集合中 name
值为 'Dandelion Bakery'
的第一个文档执行替换操作:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->replaceOne( ['name' => 'Dandelion Bakery'], ['name' => 'Flower Patisserie', 'cuisine' => 'Bakery & Cafe'], );
删除操作
要指定对第一个匹配文档执行删除操作,请对 ClientBulkWrite
实例调用 deleteOne()
方法。
以下示例指定删除 sample_restaurants.restaurants
集合中第一个 borough
值为 'Queens'
的文档:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->deleteOne( ['borough' => 'Queens'], );
要删除多个文档,请调用 deleteMany()
方法。指定的操作将删除与查询过滤匹配的所有文档。
以下示例指定删除 sample_restaurants.restaurants
集合中 name
值包含两个连续 'p'
字符的所有文档:
$restaurantCollection = $client->sample_restaurants->restaurants; $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); $bulkWrite->deleteMany( ['name' => ['$regex' => 'p{2,}']], );
执行批量操作
构造 ClientBulkWrite
实例来指定写入操作后,将其传递给 MongoDB\Client::bulkWrite()
方法。默认下,这些方法按照您在构造 ClientBulkWrite
时定义的顺序运行操作。
以下代码演示了如何使用 bulkWrite()
方法对多个命名空间执行批量写入操作:
$restaurantCollection = $client->sample_restaurants->restaurants; $movieCollection = $client->sample_mflix->movies; // Creates the bulk write command and sets the target namespace. $bulkWrite = MongoDB\ClientBulkWrite::createWithCollection($restaurantCollection); // Specifies insertion of one document. $bulkWrite->insertOne(['name' => 'Mongo Deli', 'cuisine' => 'Sandwiches']); // Specifies a `$set` update to one document with the upsert option // enabled. $bulkWrite->updateOne( ['name' => 'Dandelion Bakery'], ['$set' => ['grade' => 'B+']], ['upsert' => true], ); // Changes the target namespace. $bulkWrite = $bulkWrite->withCollection($movieCollection); // Specifies insertion of one document. $bulkWrite->insertOne(['title' => 'The Green Ray', 'year' => 1986]); // Specifies deletion of documents in which `title` has two consective // 'd' characters. $bulkWrite->deleteMany( ['title' => ['$regex' => 'd{2,}']], ); // Specifies replacement of one document. $bulkWrite->replaceOne( ['runtime' => ['$gte' => 200]], ['title' => 'Seven Samurai', 'runtime' => 203], ); // Performs the bulk write operation. $result = $client->bulkWrite($bulkWrite); // Prints a summary of results. echo 'Inserted documents: ', $result->getInsertedCount(), PHP_EOL; echo 'Modified documents: ', $result->getModifiedCount(), PHP_EOL; echo 'Deleted documents: ', $result->getDeletedCount(), PHP_EOL;
Inserted documents: 2 Modified documents: 2 Deleted documents: 200
自定义批量写入
您可以通过将大量传递给将选项值指定为参数的 ClientBulkWrite
构造函数来修改客户端批量写入操作的行为。下表描述了可在大量中设立的选项:
选项 | 说明 |
---|---|
| Specifies whether the operation bypasses document validation. This lets you
modify 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. The default is false . |
| Attaches a comment to the operation. For more information, see the insert command
fields guide in the
MongoDB Server manual. |
| Specifies a document with a list of values to improve operation readability.
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. |
| If set to true : When a single write fails, the operation stops without
performing the remaining writes and throws an exception.If set to false : When a single write fails, the operation continues to
attempt the remaining write operations, if any, then throws an exception.The default is true . |
| Specifies whether to return verbose results. The default is false . |
以下示例创建一个 ClientBulkWrite
实例并将 ordered
选项设置为 false
:
$bulkWrite = MongoDB\ClientBulkWrite::createWithCollection( $restaurantCollection, ['ordered' => false] );
注意
无序行为
无序批量操作不保证执行顺序。为了优化运行时间,顺序可以与您列出的方式不同。假设您在无序批量写入中指定以下写入操作:
$bulkWrite->insertOne(['_id' => 4045, 'title' => 'The Green Ray']); $bulkWrite->deleteOne(['_id' => 4045]);
由于库可能会先运行任一操作,因此结果可能显示一个已删除的文档,也可能显示未删除任何文档。
您还可以在调用 bulkWrite()
方法时传递选项,指定用于操作的客户端端会话或写关注(write concern)。
返回值
MongoDB\Client::bulkWrite()
方法返回一个 MongoDB\BulkWriteCommandResult
对象。该类包含以下方法:
方法 | 说明 |
---|---|
| Returns the total number of documents inserted by all
insert operations in the bulk write command. |
| Returns the total number of documents matched by all
update and replace operations in the bulk write command. |
| Returns the total number of documents modified by all update
and replace operations in the bulk write command. |
| Returns the total number of documents upserted by all update
and replace operations in the bulk write command. |
| Return the total number of documents deleted by all delete
operations in the bulk write command. |
| Returns a map of results of each successful insert operation. Each
operation is represented by an integer key, which contains a
document with information corresponding to the operation such
as the inserted _id value. |
| Returns a map of results of each successful update operation. Each
operation is represented by an integer key, which contains a
document with information corresponding to the operation. |
| Returns a map of results of each successful delete operation.
Each operation is represented by an integer key, which contains
a document with information corresponding to the operation. |
| Returns a boolean indicating whether the server acknowledged
the bulk operation. |
集合批量写入
要运行批量写入操作,请将写入操作大量传递给 MongoDB\Collection::bulkWrite()
方法。使用以下语法指定写入操作:
[ [ 'deleteMany' => [ $filter ] ], [ 'deleteOne' => [ $filter ] ], [ 'insertOne' => [ $document ] ], [ 'replaceOne' => [ $filter, $replacement, $options ] ], [ 'updateMany' => [ $filter, $update, $options ] ], [ 'updateOne' => [ $filter, $update, $options ] ], ]
提示
要学习;了解有关删除、插入、替换和更新操作的更多信息,请参阅“将数据写入MongoDB”部分中的指南。
调用 bulkWrite()
方法时,库会按照您在大量中指定的顺序自动运行写入操作。要学习;了解如何指示 bulkWrite()
以任意顺序运行写入操作,请参阅自定义批量写入操作部分。
例子
此示例对restaurants
集合运行以下写入操作:
用于插入
name
值为'Mongo's Deli'
的文档的插入操作用于更新
name
值为'Mongo's Deli'
的文档的cuisine
字段的更新操作删除操作,用于删除
borough
值为'Manhattan'
的所有文档
$restaurantCollection = $client->sample_restaurants->restaurants; $result = $restaurantCollection->bulkWrite( [ [ 'insertOne' => [ ['name' => 'Mongo\'s Deli'], ['cuisine' => 'Sandwiches'], ['borough' => 'Manhattan'], ['restaurant_id' => '1234'], ], ], [ 'updateOne' => [ ['name' => 'Mongo\'s Deli'], ['$set' => ['cuisine' => 'Sandwiches and Salads']], ], ], [ 'deleteMany' => [ ['borough' => 'Manhattan'], ], ], ] );
注意
当库运行批量操作时,它会使用目标集合的写关注(write concern)。无论执行顺序如何,驾驶员在尝试所有操作后都会报告所有写关注(write concern)错误。
自定义批量写入操作
您可以通过传递指定选项值的大量作为参数来修改MongoDB\Collection::bulkWrite()
方法的行为。 下表描述了可在大量中设立的选项:
选项 | 说明 |
---|---|
| Specifies whether the operation bypasses document validation. This lets you
modify 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. The default is false . |
| Sets the codec to use for encoding or decoding documents. Bulk writes
use the codec for insertOne() and replaceOne() operations.
For more information, see the Codecs guide. |
| Sets the write concern for the operation.
For more information, see Write Concern
in the MongoDB Server manual. |
| Specifies a document with a list of values to improve operation readability.
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. |
| If set to true : When a single write fails, the operation stops without
performing the remaining writes and throws an exception.If set to false : When a single write fails, the operation continues to
attempt the remaining write operations, if any, then throws an exception.The default is true . |
| Attaches a comment to the operation. For more information, see the insert command
fields guide in the
MongoDB Server manual. |
| Specifies the client session to associate with the operation. |
以下示例调用bulkWrite()
方法执行插入和删除操作,并将ordered
选项设置为false
:
$result = $restaurantCollection->bulkWrite( [ [ 'insertOne' => [ ['name' => 'Mongo\'s Pizza'], ['cuisine' => 'Italian'], ['borough' => 'Queens'], ['restaurant_id' => '5678'], ], ], [ 'deleteOne' => [ ['restaurant_id' => '5678'], ], ], ], ['ordered' => false] );
如果库先运行插入操作,则会删除一个文档。 如果它先运行删除操作,则不会删除任何文档。
注意
无序行为
无序批量操作不保证执行顺序。 为了优化运行时间,顺序可以与您列出的方式不同。
返回值
MongoDB\Collection::bulkWrite()
方法返回一个 MongoDB\BulkWriteResult
对象。该类包含以下方法:
方法 | 说明 |
---|---|
| Returns the total number of documents inserted by all
insert operations in the bulk write command. |
| Returns a map of _id field values for documents
inserted by all insert operations in the bulk write command. |
| Returns the total number of documents matched by all
update and replace operations in the bulk write command. |
| Returns the total number of documents modified by all update
and replace operations in the bulk write command. |
| Returns the total number of documents upserted by all update
and replace operations in the bulk write command. |
| Returns a map of _id field values for documents
upserted by all update and replace operations in the bulk write
command. |
| Return the total number of documents deleted by all delete
operations in the bulk write command. |
| Returns a boolean indicating whether the server acknowledged
the bulk operation. |
更多信息
要了解如何执行单个写入操作,请参阅以下指南:
API 文档
要进一步了解本指南所讨论的任何方法或类型,请参阅以下 API 文档: