forked from mongodb/docs-kotlin-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbulk-write.txt
More file actions
656 lines (488 loc) · 22.3 KB
/
Copy pathbulk-write.txt
File metadata and controls
656 lines (488 loc) · 22.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
.. _kotlin-sync-bulk-write:
=====================
Bulk Write Operations
=====================
.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:class: singlecol
.. facet::
:name: genre
:values: reference
.. meta::
:keywords: insert, update, replace, code example, multiple changes
Overview
--------
In this guide, you can learn how to perform multiple write operations in
a single database call by using **bulk write operations**.
Consider a scenario in which you want to insert a document,
update multiple other documents, then delete a document. If you use
individual methods, each operation requires its own database call.
By using a bulk write operation, you can perform multiple write operations in
fewer database calls. You can perform bulk write operations at the following levels:
- :ref:`Collection <kotlin-sync-coll-bulk-write>`: You can use the
``MongoCollection.bulkWrite()`` method to perform bulk write operations on a
single collection. In this method, each kind of write operation requires at
least one database call. For example, ``MongoCollection.bulkWrite()`` puts multiple update
operations in one call, but makes two separate calls to the database for an insert
operation and a replace operation.
- :ref:`Client <kotlin-sync-client-bulk-write>`: If your application connects to
{+mdb-server+} version 8.0 or later, you can use the ``MongoClient.bulkWrite()``
method to perform bulk write operations on multiple collections and databases
in the same cluster. This method performs all write operations
in one database call.
Sample Data
~~~~~~~~~~~
The examples in this guide use the ``sample_restaurants.restaurants``
and ``sample_mflix.movies`` collections from the :atlas:`Atlas sample
datasets </sample-data>`. To learn how to create a free MongoDB Atlas
cluster and load the sample datasets, see the :atlas:`Get Started with
Atlas </getting-started>` guide.
The documents in these collections are modeled by the following
{+language+} data classes:
.. literalinclude:: /includes/write/client-bulk-write.kt
:start-after: start-data-classes
:end-before: end-data-classes
:language: kotlin
:copyable:
:dedent:
.. _kotlin-sync-coll-bulk-write:
Collection Bulk Write
---------------------
Bulk write operations contain one or more write operations. To perform a bulk
write operation at the collection level, pass a ``List`` of ``WriteModel``
documents to the ``MongoCollection.bulkWrite()`` method. A ``WriteModel`` is a
model that represents a write operation.
For each write operation you want to perform, create an instance of one of
the following classes that inherit from ``WriteModel``:
- ``InsertOneModel``
- ``UpdateOneModel``
- ``UpdateManyModel``
- ``ReplaceOneModel``
- ``DeleteOneModel``
- ``DeleteManyModel``
The following sections show how to create and use instances of the
preceding classes. The :ref:`kotlin-sync-bulkwrite-method` section
demonstrates how to pass a list of models to the ``bulkWrite()`` method
to perform the bulk operation.
Insert Operations
~~~~~~~~~~~~~~~~~
To perform an insert operation, create an ``InsertOneModel`` instance and specify
the document you want to insert.
The following example creates an instance of ``InsertOneModel``:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-insert-one
:end-before: end-bulk-insert-one
:language: kotlin
:copyable:
:dedent:
To insert multiple documents, create an instance of ``InsertOneModel``
for each document.
.. important::
When performing a bulk operation, the ``InsertOneModel`` cannot
instruct insertion of a document that has an ``_id`` value that already
exists in the collection. In this situation, the driver throws a
``MongoBulkWriteException``.
Update Operations
~~~~~~~~~~~~~~~~~
To update a document, create an instance of ``UpdateOneModel`` and pass
the following arguments:
- A **query filter** that specifies the criteria used to match documents in your collection
- The update operation you want to perform. For more information about update
operators, see the :manual:`Field Update Operators
</reference/operator/update-field/>` guide in the {+mdb-server+} manual.
An ``UpdateOneModel`` instance specifies an update for *the first*
document that matches your query filter.
The following example creates an instance of ``UpdateOneModel``:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-update-one
:end-before: end-bulk-update-one
:language: kotlin
:copyable:
:dedent:
If multiple documents match the query filter specified in
the ``UpdateOneModel`` instance, the operation updates the first
result. You can specify a sort in an ``UpdateOptions`` instance to apply
an order to matched documents before the server performs the update
operation, as shown in the following code:
.. code-block:: kotlin
val opts = UpdateOptions().sort(Sorts.ascending(Restaurant::name.name))
To update multiple documents, create an instance of ``UpdateManyModel`` and pass
the same arguments as for ``UpdateOneModel``. The ``UpdateManyModel``
class specifies updates for *all* documents that match your query
filter.
The following example creates an instance of ``UpdateManyModel`` to
direct the driver to update all matching documents:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-update-many
:end-before: end-bulk-update-many
:language: kotlin
:copyable:
:dedent:
Replace Operations
~~~~~~~~~~~~~~~~~~
A replace operation removes all fields and values of a specified document and
replaces them with new fields and values that you specify. To perform a
replace operation, create an instance of ``ReplaceOneModel`` and pass a
query filter and the fields and values you want to replace the matching
document with.
The following example creates an instance of ``ReplaceOneModel``:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-replace-one
:end-before: end-bulk-replace-one
:language: kotlin
:copyable:
:dedent:
If multiple documents match the query filter specified in
the ``ReplaceOneModel`` instance, the operation replaces the first
result. You can specify a sort in a ``ReplaceOptions`` instance to apply
an order to matched documents before the server performs the replace
operation, as shown in the following code:
.. code-block:: kotlin
val opts = ReplaceOptions().sort(Sorts.ascending(Restaurant::name.name))
.. tip:: Replace Multiple Documents
To replace multiple documents, create an instance of
``ReplaceOneModel`` for each document.
Delete Operations
~~~~~~~~~~~~~~~~~
To delete a document, create an instance of ``DeleteOneModel`` and pass a
query filter specifying the document you want to delete. A
``DeleteOneModel`` instance provides instructions to delete
only *the first* document that matches your query filter.
The following example creates an instance of ``DeleteOneModel``:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-delete-one
:end-before: end-bulk-delete-one
:language: kotlin
:copyable:
:dedent:
To delete multiple documents, create an instance of ``DeleteManyModel`` and pass a
query filter specifying the document you want to delete. An instance of
``DeleteManyModel`` provides instructions to remove *all* documents that
match your query filter.
The following example creates an instance of ``DeleteManyModel``:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-delete-many
:end-before: end-bulk-delete-many
:language: kotlin
:copyable:
:dedent:
.. _kotlin-sync-bulkwrite-method:
Perform the Bulk Operation
~~~~~~~~~~~~~~~~~~~~~~~~~~
After you define a model instance for each operation you want to perform,
pass a list of these instances to the ``bulkWrite()`` method.
By default, the method runs the operations in the order
specified by the list of models.
The following example performs multiple write operations by using the
``bulkWrite()`` method:
.. io-code-block::
.. input:: /includes/write/bulk.kt
:start-after: start-bulk-write-mixed
:end-before: end-bulk-write-mixed
:language: kotlin
:dedent:
.. output::
AcknowledgedBulkWriteResult{insertedCount=1, matchedCount=5, removedCount=3,
modifiedCount=2, upserts=[], inserts=[BulkWriteInsert{index=0,
id=BsonObjectId{value=...}}]}
If any of the write operations fail, the {+driver-short+} raises a
``BulkWriteError`` and does not perform any further operations.
``BulkWriteError`` provides a ``details`` field that includes the
operation that failed, and details about the exception.
.. note::
When the driver runs a bulk operation, it uses the write concern of the
target collection. The driver reports all write concern errors after
attempting all operations, regardless of execution order.
Customize Bulk Write Operation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``bulkWrite()`` method optionally accepts a parameter which
specifies options you can use to configure the bulk write
operation. If you don't specify any options, the driver performs the
bulk operation with default settings.
The following table describes the setter methods that you can use to
configure a ``BulkWriteOptions`` instance:
.. list-table::
:widths: 30 70
:header-rows: 1
* - Property
- Description
* - ``ordered()``
- | 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.
| Defaults to ``true``.
* - ``bypassDocumentValidation()``
- | Specifies whether the update operation bypasses document validation. This lets you
update documents that don't meet the schema validation requirements, if any
exist. For more information about schema validation, see :manual:`Schema
Validation </core/schema-validation/#schema-validation>` in the MongoDB
Server manual.
| Defaults to ``false``.
* - ``comment()``
- | Sets a comment to attach to the operation.
* - ``let()``
- | Provides a map of parameter names and values to set top-level
variables for the operation. Values must be constant or closed
expressions that don't reference document fields.
The following code creates options and uses the ``ordered(false)`` option to
specify an unordered bulk write. Then, the example uses the
``bulkWrite()`` method to perform a bulk operation:
.. literalinclude:: /includes/write/bulk.kt
:start-after: start-bulk-write-unordered
:end-before: end-bulk-write-unordered
:language: kotlin
:copyable:
:dedent:
If any of the write operations in an unordered bulk write fail, the {+driver-short+}
reports the errors only after attempting all operations.
.. note::
Unordered bulk operations do not guarantee an order of execution. The
order can differ from the way you list them to optimize the runtime.
Return Value
~~~~~~~~~~~~
The ``bulkWrite()`` method returns a ``BulkWriteResult`` object. You can
access the following information from a ``BulkWriteResult`` instance:
.. list-table::
:widths: 30 70
:header-rows: 1
* - Property
- Description
* - ``wasAcknowledged()``
- | Indicates if the server acknowledged the write operation.
* - ``getDeletedCount()``
- | The number of documents deleted, if any.
* - ``getInsertedCount()``
- | The number of documents inserted, if any.
* - ``getInserts()``
- | The list of inserted documents, if any.
* - ``getMatchedCount()``
- | The number of documents matched for an update, if applicable.
* - ``getModifiedCount()``
- | The number of documents modified, if any.
* - ``getUpserts()``
- | The list of upserted documents, if any.
.. _kotlin-sync-client-bulk-write:
Client Bulk Write
-----------------
When connecting to a deployment running {+mdb-server+} 8.0 or later,
you can use the ``MongoClient.bulkWrite()`` method to write
to multiple databases and collections in the same cluster. The
``MongoClient.bulkWrite()`` method performs all write operations in a
single call.
The ``MongoClient.bulkWrite()`` method takes a
list of ``ClientNamespacedWriteModel`` instances to represent different write operations.
You can construct instances of the ``ClientNamespacedWriteModel`` interface by using
instance methods. For example, an instance of ``ClientNamespacedInsertOneModel`` represents an
operation to insert one document, and you can create this model by using
the ``ClientNamespacedWriteModel.insertOne()`` method.
The models and their corresponding instance methods are described
in the table below.
.. list-table::
:header-rows: 1
* - Model
- Instance Method
- Description
- Parameters
* - ``ClientNamespacedInsertOneModel``
- ``insertOne()``
- Creates a model to insert a document into the ``namespace``.
- ``namespace``: Database and collection to write to
``document``: Document to insert
* - ``ClientNamespacedUpdateOneModel``
- ``updateOne()``
- Creates a model to update the first document in the ``namespace``
that matches ``filter``.
- ``namespace``: Database and collection to write to
``filter``: Filter that selects which document to update
``update``: Update to apply to matching document
``updatePipeline``: Update pipeline to apply to matching document
``options``: *(optional)* Options to apply when updating document
You must pass a value for either the ``update`` or ``updatePipeline``
parameter.
* - ``ClientNamespacedUpdateManyModel``
- ``updateMany()``
- Creates a model to update all documents in the ``namespace`` that match
``filter``.
- ``namespace``: Database and collection to write to
``filter``: Filter that selects which documents to update
``update``: Update to apply to matching documents
``updatePipeline``: Update pipeline to apply to matching documents
``options``: *(optional)* Options to apply when updating documents
You must pass a value for either the ``update`` or ``updatePipeline``
parameter.
* - ``ClientNamespacedReplaceOneModel``
- ``replaceOne()``
- Creates a model to replace the first document in the ``namespace`` that
matches ``filter``.
- ``namespace``: Database and collection to write to
``filter``: Filter that selects which document to replace
``replacement``: Replacement document
``options``: *(optional)* Options to apply when replacing documents
* - ``ClientNamespacedDeleteOneModel``
- ``deleteOne()``
- Creates a model to delete the first document in the ``namespace`` that
matches ``filter``.
- ``namespace``: Database and collection to write to
``filter``: Filter that selects which document to delete
``option``: *(optional)* Options to apply when deleting document
* - ``ClientNamespacedDeleteManyModel``
- ``deleteMany()``
- Creates a model to delete all documents in the ``namespace`` that match
``filter``.
- ``namespace``: Database and collection to write to
``filter``: Filter that selects which documents to delete
``option``: *(optional)* Options to apply when deleting documents
The following sections provide some examples of how to create models and use
the client ``bulkWrite()`` method.
Insert Operations
~~~~~~~~~~~~~~~~~
This example shows how to create models that contain instructions to
insert two documents. One document is inserted into the ``sample_restaurants.restaurants``
collection, and the other document is inserted into the ``sample_mflix.movies`` collection.
The ``MongoNamespace`` instance defines the target database and collection that
each write operation applies to.
.. literalinclude:: /includes/write/client-bulk-write.kt
:start-after: start-insert-models
:end-before: end-insert-models
:language: kotlin
:copyable:
:dedent:
.. _kotlin-sync-client-bulk-write-update:
Update Operation
~~~~~~~~~~~~~~~~
The following example shows how to use the ``bulkWrite()`` method to update
existing documents in the ``sample_restaurants.restaurants`` and
``sample_mflix.movies`` collections:
.. literalinclude:: /includes/write/client-bulk-write.kt
:start-after: start-update-models
:end-before: end-update-models
:language: kotlin
:copyable:
:dedent:
This example increments the value of the ``stars`` field by ``1`` in the
document that has a ``name`` value of ``"Villa Berulia"`` in the
``restaurants`` collection. It also sets the value of the ``seen`` field
to ``true`` in all documents that have a ``title`` value of ``"Carrie"``
in the ``movies`` collection.
If multiple documents match the query filter specified in
a ``ClientNamespacedUpdateOneModel`` instance, the operation updates the
first result. You can specify a sort order in a `ClientUpdateOneOptions
<{+core-api+}/client/model/bulk/ClientUpdateOneOptions.html>`__
instance to apply an order to matched documents before the server
performs the update operation, as shown in the following code:
.. code-block:: kotlin
val options = ClientUpdateOneOptions
.clientUpdateOneOptions()
.sort(Sorts.ascending("_id"))
.. _kotlin-sync-client-bulk-write-replace:
Replace Operations
~~~~~~~~~~~~~~~~~~
The following example shows how to create models to replace
existing documents in the ``sample_restaurants.restaurants`` and
``sample_mflix.movies`` collections:
.. literalinclude:: /includes/write/client-bulk-write.kt
:start-after: start-replace-models
:end-before: end-replace-models
:language: kotlin
:copyable:
:dedent:
After this example runs successfully, the document that has an ``_id`` value of ``1``
in the ``restaurants`` collection is replaced with a new document. The document in
the ``movies`` collection that has an ``_id`` value of ``1``
is also replaced with a new document.
If multiple documents match the query filter specified in
a ``ClientNamespacedReplaceOneModel`` instance, the operation replaces the
first result. You can specify a sort order in a `ClientReplaceOneOptions
<{+core-api+}/client/model/bulk/ClientReplaceOneOptions.html>`__
instance to apply an order to matched documents before the driver
performs the replace operation, as shown in the following code:
.. code-block:: kotlin
val options = ClientReplaceOneOptions
.clientReplaceOneOptions()
.sort(Sorts.ascending("_id"))
Perform the Bulk Operation
~~~~~~~~~~~~~~~~~~~~~~~~~~
After you define a ``ClientNamespacedWriteModel`` instance for each
operation you want to perform, pass a list of these instances to the
client ``bulkWrite()`` method. By default, the method runs the
operations in the order they're specified.
The following example performs multiple write operations by using the
``bulkWrite()`` method:
.. io-code-block::
:copyable:
.. input:: /includes/write/client-bulk-write.kt
:start-after: start-perform
:end-before: end-perform
:emphasize-lines: 18-19
:language: kotlin
:dedent:
.. output::
AcknowledgedSummaryClientBulkWriteResult{insertedCount=1, matchedCount=1, ...}
If any of the write operations fail, the driver raises a
``ClientBulkWriteException`` and does not perform any further individual operations.
``ClientBulkWriteException`` includes a ``BulkWriteError`` that can be accessed by using the
``ClientBulkWriteException.getWriteErrors()`` method, which provides details of the
individual failure.
.. _kotlin-sync-client-bulk-write-options:
Customize Bulk Write
~~~~~~~~~~~~~~~~~~~~
You can pass an instance of ``ClientBulkWriteOptions`` to the
``bulkWrite()`` method to customize how the driver performs the bulk write
operation.
Order of Execution
``````````````````
By default, the driver runs the individual operations in a bulk
operation in the order that you specify them until an error occurs, or
until the operation completes successfully.
However, you can pass ``false`` to the ``ordered()`` method when creating
a ``ClientBulkWriteOptions`` instance to direct the driver to perform
write operations in an unordered way. When using the unordered option,
an error-producing operation does not prevent the driver from running
other write operations in the bulk write operation.
The following code sets the ``ordered`` option to ``false`` in an
instance of ``ClientBulkWriteOptions`` and performs a bulk write operation to
insert multiple documents.
.. literalinclude:: /includes/write/client-bulk-write.kt
:start-after: start-options
:end-before: end-options
:emphasize-lines: 3-5, 23-24
:language: kotlin
:copyable:
:dedent:
Even though the write operation inserting a document with a duplicate key results
in an error, the other operations are performed because the write operation is
unordered.
Additional Information
----------------------
To learn how to perform individual write operations, see the following guides:
- :ref:`kotlin-sync-write-insert`
- :ref:`kotlin-sync-write-update`
- :ref:`kotlin-sync-write-delete`
- :ref:`kotlin-sync-write-replace`
API Documentation
~~~~~~~~~~~~~~~~~
To learn more about any of the methods or types discussed in this
guide, see the following API Documentation:
- Collection Bulk Write
- `bulkWrite() <{+driver-api+}/-mongo-collection/bulk-write.html>`__
- `InsertOneModel <{+core-api+}/client/model/InsertOneModel.html>`__
- `UpdateOneModel <{+core-api+}/client/model/UpdateOneModel.html>`__
- `UpdateManyModel <{+core-api+}/client/model/UpdateManyModel.html>`__
- `ReplaceOneModel <{+core-api+}/client/model/ReplaceOneModel.html>`__
- `DeleteOneModel <{+core-api+}/client/model/DeleteOneModel.html>`__
- `DeleteManyModel <{+core-api+}/client/model/DeleteManyModel.html>`__
- `BulkWriteResult <{+core-api+}/bulk/BulkWriteResult.html>`__
- `BulkWriteError <{+core-api+}/bulk/BulkWriteError.html>`__
- `MongoBulkWriteException <{+core-api+}/MongoBulkWriteException.html>`__
- Client Bulk Write
- `bulkWrite() <{+driver-api+}/-mongo-cluster/bulk-write.html>`__
- `ClientNamespacedWriteModel
<{+core-api+}/client/model/bulk/ClientNamespacedWriteModel.html>`__
- `MongoNamespace <{+core-api+}/MongoNamespace.html>`__
- `ClientBulkWriteOptions <{+core-api+}/client/model/bulk/ClientBulkWriteOptions.html>`__
- `ClientBulkWriteResult <{+core-api+}/client/model/bulk/ClientBulkWriteResult.html>`__