diff --git a/examples/src/test/kotlin/BulkTest.kt b/examples/src/test/kotlin/BulkTest.kt index f3e889a9..19d986eb 100644 --- a/examples/src/test/kotlin/BulkTest.kt +++ b/examples/src/test/kotlin/BulkTest.kt @@ -14,9 +14,11 @@ import java.util.* import kotlin.test.* // :snippet-start: bulk-data-model -data class SampleDoc( +data class Person( @BsonId val id: Int, - val x: Int? = null + val name: String, + val age: Int? = null, + val location: String? = null ) // :snippet-end: @@ -26,15 +28,16 @@ internal class BulkTest { val config = getConfig() val client = MongoClient.create(config.connectionUri) val database = client.getDatabase("sample_db") - val collection = database.getCollection("sample_docs") + val collection = database.getCollection("people") @BeforeAll @JvmStatic fun beforeAll() { runBlocking { val sampleDocuments = listOf( - SampleDoc(1), - SampleDoc(2) + Person(1, "Karen Sandoval", 31), + Person(2, "William Chin", 54), + Person(8, "Shayla Ray", 20) ) collection.insertMany(sampleDocuments) } @@ -53,16 +56,14 @@ internal class BulkTest { @Test fun insertOperationTest() = runBlocking { // :snippet-start: insert-one - val doc3 = InsertOneModel(SampleDoc(3)) - val doc4 = InsertOneModel(SampleDoc(4)) + val juneDoc = InsertOneModel(Person(3, "June Carrie", 17)) + val kevinDoc = InsertOneModel(Person(4, "Kevin Moss", 22)) // :snippet-end: // :snippet-start: bulk-write-exception - val doc5 = InsertOneModel(SampleDoc(1)) - val doc6 = InsertOneModel(SampleDoc(3)) try { val bulkOperations = listOf( - (doc5), - (doc6) + (InsertOneModel(Person(1, "James Smith", 13))), + (InsertOneModel(Person(3, "Colin Samuels"))) ) val bulkWrite = collection.bulkWrite(bulkOperations) assertFalse(bulkWrite.wasAcknowledged()) // :remove: @@ -72,8 +73,9 @@ internal class BulkTest { // :snippet-end: // Junit test for the above code val expected = listOf( - SampleDoc(1), - SampleDoc(2) + Person(1, "Karen Sandoval", 31), + Person(2, "William Chin", 54), + Person(8, "Shayla Ray", 20) ) assertEquals(expected, collection.find().toList()) } @@ -82,7 +84,7 @@ internal class BulkTest { fun replaceOneTest() = runBlocking { // :snippet-start: replace-one val filter = Filters.eq("_id", 1) - val insert = SampleDoc(1, 4) + val insert = Person(1, "Celine Stork", location = "San Diego, CA") val doc = ReplaceOneModel(filter, insert) // :snippet-end: // Junit test for the above code @@ -94,8 +96,8 @@ internal class BulkTest { fun updateOneTest() = runBlocking { // :snippet-start: update-one val filter = Filters.eq("_id", 2) - val update = Updates.set(SampleDoc::x.name, 8) - val doc = UpdateOneModel(filter, update) + val update = Updates.inc(Person::age.name, 1) + val doc = UpdateOneModel(filter, update) // :snippet-end: // Junit test for the above code val updateTest = collection.bulkWrite(listOf(doc)) @@ -105,66 +107,71 @@ internal class BulkTest { @Test fun deleteOneTest() = runBlocking { // :snippet-start: delete - val filter = Filters.eq("_id", 1) - val doc = DeleteOneModel(filter) + val deleteId1 = DeleteOneModel(Filters.eq("_id", 1)) + val deleteAgeLt30 = DeleteManyModel(Filters.lt(Person::age.name, 30)) // :snippet-end: // Junit test for the above code - val deleteTest = collection.bulkWrite(listOf(doc)) + val deleteTest = collection.bulkWrite(listOf(deleteId1, deleteAgeLt30)) assertTrue(deleteTest.wasAcknowledged()) - assertTrue(collection.find(filter).toList().isEmpty()) + val expected = listOf( + Person(2, "William Chin", 54), + ) + assertEquals(expected, collection.find().toList()) } @Test fun orderOfOperationsTest() = runBlocking { // :snippet-start: ordered - val doc1= InsertOneModel(SampleDoc(3)) - val doc2 = ReplaceOneModel( + val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37)) + val replaceMdl = ReplaceOneModel( Filters.eq("_id", 1), - SampleDoc(1, 2) + Person(1, "Sandy Kane", location = "Helena, MT") ) - val doc3 = UpdateOneModel( - Filters.eq("_id", 3), - Updates.set(SampleDoc::x.name, 2) + val updateMdl = UpdateOneModel( + Filters.eq("_id", 6), + Updates.set(Person::name.name, "Zaynab Hassan") ) - val doc4 = DeleteManyModel(Filters.eq(SampleDoc::x.name, 2)) + val deleteMdl = DeleteManyModel(Filters.gt(Person::age.name, 50)) val bulkOperations = listOf( - doc1, - doc2, - doc3, - doc4 + insertMdl, + replaceMdl, + updateMdl, + deleteMdl ) - val update = collection.bulkWrite(bulkOperations) + val result = collection.bulkWrite(bulkOperations) // :snippet-end: // Junit test for the above code - assertTrue(update.wasAcknowledged()) + assertTrue(result.wasAcknowledged()) + collection.drop() } @Test fun unorderedExecutionTest() = runBlocking { - val doc1 = InsertOneModel(SampleDoc(3)) - val doc2 = ReplaceOneModel( + val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37)) + val replaceMdl = ReplaceOneModel( Filters.eq("_id", 1), - SampleDoc(1, 2) + Person(1, "Sandy Kane", location = "Helena, MT") ) - val doc3 = UpdateOneModel( - Filters.eq("_id", 3), - Updates.set(SampleDoc::x.name, 2) - ) - val doc4 = DeleteManyModel(Filters.eq(SampleDoc::x.name, 2)) + val updateMdl = UpdateOneModel( + Filters.eq("_id", 6), + Updates.set(Person::name.name, "Zaynab Hassan") + ) + val deleteMdl = DeleteManyModel(Filters.gt(Person::age.name, 50)) val bulkOperations = listOf( - doc1, - doc2, - doc3, - doc4 + insertMdl, + replaceMdl, + updateMdl, + deleteMdl ) // :snippet-start: unordered val options = BulkWriteOptions().ordered(false) - val unorderedUpdate = collection.bulkWrite(bulkOperations, options) + val unorderedResult = collection.bulkWrite(bulkOperations, options) // :snippet-end: // Junit test for the above code - assertTrue(unorderedUpdate.wasAcknowledged()) + assertTrue(unorderedResult.wasAcknowledged()) + collection.drop() } } \ No newline at end of file diff --git a/snooty.toml b/snooty.toml index 9fedda06..aed7eccc 100644 --- a/snooty.toml +++ b/snooty.toml @@ -20,7 +20,7 @@ driver = "kotlin" driver-short = "Kotlin driver" driver-long = "MongoDB Kotlin Driver" version = "4.10" -full-version = "4.10.1" +full-version = "{+version+}.1" mdb-server = "MongoDB server" kotlin-docs = "https://kotlinlang.org/docs" diff --git a/source/examples/generated/BulkTest.snippet.bulk-data-model.kt b/source/examples/generated/BulkTest.snippet.bulk-data-model.kt index 2209f3ec..a41f4f03 100644 --- a/source/examples/generated/BulkTest.snippet.bulk-data-model.kt +++ b/source/examples/generated/BulkTest.snippet.bulk-data-model.kt @@ -1,4 +1,6 @@ -data class SampleDoc( +data class Person( @BsonId val id: Int, - val x: Int? = null + val name: String, + val age: Int? = null, + val location: String? = null ) diff --git a/source/examples/generated/BulkTest.snippet.bulk-write-exception.kt b/source/examples/generated/BulkTest.snippet.bulk-write-exception.kt index e621240f..044ddb61 100644 --- a/source/examples/generated/BulkTest.snippet.bulk-write-exception.kt +++ b/source/examples/generated/BulkTest.snippet.bulk-write-exception.kt @@ -1,9 +1,7 @@ -val doc5 = InsertOneModel(SampleDoc(1)) -val doc6 = InsertOneModel(SampleDoc(3)) try { val bulkOperations = listOf( - (doc5), - (doc6) + (InsertOneModel(Person(1, "James Smith", 13))), + (InsertOneModel(Person(3, "Colin Samuels"))) ) val bulkWrite = collection.bulkWrite(bulkOperations) } catch (e: MongoBulkWriteException) { diff --git a/source/examples/generated/BulkTest.snippet.delete.kt b/source/examples/generated/BulkTest.snippet.delete.kt index 61411f51..b4ddff9f 100644 --- a/source/examples/generated/BulkTest.snippet.delete.kt +++ b/source/examples/generated/BulkTest.snippet.delete.kt @@ -1,2 +1,2 @@ -val filter = Filters.eq("_id", 1) -val doc = DeleteOneModel(filter) +val deleteId1 = DeleteOneModel(Filters.eq("_id", 1)) +val deleteAgeLt30 = DeleteManyModel(Filters.lt(Person::age.name, 30)) diff --git a/source/examples/generated/BulkTest.snippet.insert-one.kt b/source/examples/generated/BulkTest.snippet.insert-one.kt index e4e82e44..e3d16cf8 100644 --- a/source/examples/generated/BulkTest.snippet.insert-one.kt +++ b/source/examples/generated/BulkTest.snippet.insert-one.kt @@ -1,2 +1,2 @@ -val doc3 = InsertOneModel(SampleDoc(3)) -val doc4 = InsertOneModel(SampleDoc(4)) +val juneDoc = InsertOneModel(Person(3, "June Carrie", 17)) +val kevinDoc = InsertOneModel(Person(4, "Kevin Moss", 22)) diff --git a/source/examples/generated/BulkTest.snippet.ordered.kt b/source/examples/generated/BulkTest.snippet.ordered.kt index b6c426e8..6c3a05d1 100644 --- a/source/examples/generated/BulkTest.snippet.ordered.kt +++ b/source/examples/generated/BulkTest.snippet.ordered.kt @@ -1,19 +1,19 @@ -val doc1= InsertOneModel(SampleDoc(3)) -val doc2 = ReplaceOneModel( +val insertMdl = InsertOneModel(Person(6, "Zaynab Omar", 37)) +val replaceMdl = ReplaceOneModel( Filters.eq("_id", 1), - SampleDoc(1, 2) + Person(1, "Sandy Kane", location = "Helena, MT") ) -val doc3 = UpdateOneModel( - Filters.eq("_id", 3), - Updates.set(SampleDoc::x.name, 2) +val updateMdl = UpdateOneModel( + Filters.eq("_id", 6), + Updates.set(Person::name.name, "Zaynab Hassan") ) -val doc4 = DeleteManyModel(Filters.eq(SampleDoc::x.name, 2)) +val deleteMdl = DeleteManyModel(Filters.gt(Person::age.name, 50)) val bulkOperations = listOf( - doc1, - doc2, - doc3, - doc4 + insertMdl, + replaceMdl, + updateMdl, + deleteMdl ) -val update = collection.bulkWrite(bulkOperations) +val result = collection.bulkWrite(bulkOperations) diff --git a/source/examples/generated/BulkTest.snippet.replace-one.kt b/source/examples/generated/BulkTest.snippet.replace-one.kt index 70bc4506..28ea5e34 100644 --- a/source/examples/generated/BulkTest.snippet.replace-one.kt +++ b/source/examples/generated/BulkTest.snippet.replace-one.kt @@ -1,3 +1,3 @@ val filter = Filters.eq("_id", 1) -val insert = SampleDoc(1, 4) +val insert = Person(1, "Celine Stork", location = "San Diego, CA") val doc = ReplaceOneModel(filter, insert) diff --git a/source/examples/generated/BulkTest.snippet.unordered.kt b/source/examples/generated/BulkTest.snippet.unordered.kt index d71c9346..def70936 100644 --- a/source/examples/generated/BulkTest.snippet.unordered.kt +++ b/source/examples/generated/BulkTest.snippet.unordered.kt @@ -1,2 +1,2 @@ val options = BulkWriteOptions().ordered(false) -val unorderedUpdate = collection.bulkWrite(bulkOperations, options) +val unorderedResult = collection.bulkWrite(bulkOperations, options) diff --git a/source/examples/generated/BulkTest.snippet.update-one.kt b/source/examples/generated/BulkTest.snippet.update-one.kt index 9c3a77da..ea8c3464 100644 --- a/source/examples/generated/BulkTest.snippet.update-one.kt +++ b/source/examples/generated/BulkTest.snippet.update-one.kt @@ -1,3 +1,3 @@ val filter = Filters.eq("_id", 2) -val update = Updates.set(SampleDoc::x.name, 8) -val doc = UpdateOneModel(filter, update) +val update = Updates.inc(Person::age.name, 1) +val doc = UpdateOneModel(filter, update) diff --git a/source/fundamentals/crud/write-operations/bulk.txt b/source/fundamentals/crud/write-operations/bulk.txt index 5c55324e..1a591bdb 100644 --- a/source/fundamentals/crud/write-operations/bulk.txt +++ b/source/fundamentals/crud/write-operations/bulk.txt @@ -4,8 +4,6 @@ Bulk Operations =============== -.. default-domain:: mongodb - .. contents:: On this page :local: :backlinks: none @@ -16,33 +14,32 @@ Overview -------- In this guide, you can learn how to use bulk operations in the -MongoDB Kotlin Driver. +{+driver-long+}. -To perform a create, replace, update, or delete operation, -use its corresponding method. For example, to insert one document, -update multiple documents, and delete one document in your collection, -use the ``insertOne()``, ``updateMany()`` and ``deleteOne()`` methods. +For individual CRUD operations, you can use the relevant method. For +example, to insert one document and then update multiple documents, you +can use the ``insertOne()`` method and the ``updateMany()`` method. -The ``MongoClient`` performs these operations by making a call for each -operation to the database. You can reduce the number of calls to the -database to one by using bulk operations. +The ``MongoClient`` performs these operations by making a request to the +database corresponding to each operation. You can reduce the number of +calls to the database by using bulk operations. Performing Bulk Operations -------------------------- Bulk operations consist of a large number of write operations. To perform -a bulk operation, pass a ``List`` of ``WriteModel`` documents to the -``bulkWrite()`` method. A ``WriteModel`` is a model that represents any -of the write operations. +a bulk operation, pass a ``List`` containing ``WriteModel`` documents to the +``bulkWrite()`` method. A ``WriteModel`` is a model that represents a single +write operation. -The following sections show how to create and use each ``WriteModel`` -document. The examples in each section contain the following documents -in a collection: +The following sections show how to create and use each variation of the ``WriteModel`` +type. The examples in each section use the following documents in the ``people`` collection: .. code-block:: json - { "_id": 1 } - { "_id": 2 } + { "_id": 1, "name": "Karen Sandoval", "age": 31 } + { "_id": 2, "name": "William Chin", "age": 54 } + { "_id": 8, "name": "Shayla Ray", "age": 20 } This data is modeled with the following Kotlin data class: @@ -67,19 +64,20 @@ Example ``````` The following example creates an ``InsertOneModel`` for two documents -where the ``_id`` values are "3" and "4": +describing people: .. literalinclude:: /examples/generated/BulkTest.snippet.insert-one.kt :language: kotlin .. important:: - When performing a ``bulkWrite()``, the ``InsertOneModel`` cannot + When performing a ``bulkWrite()`` operation, the ``InsertOneModel`` cannot insert a document with an ``_id`` that already exists in the - collection. Instead, the method throws a ``MongoBulkWriteException``. + collection. In this case, the driver throws a ``MongoBulkWriteException``. - The following example tries to insert two documents where the ``_id`` is - "1" and "3": + The following example tries to insert two documents where the ``_id`` + values are ``1`` and ``3``. Since there is already a document with an ``_id`` + of ``1`` in the collection, the operation results in an error: .. io-code-block:: @@ -94,8 +92,8 @@ where the ``_id`` values are "3" and "4": Write errors: [BulkWriteError{index=0, code=11000, message='E11000 duplicate key error collection: crudOps.bulkWrite index: _id_ dup key: { _id: 1 }', details={}}]. - To see why the document with the ``_id`` of "3" didn't insert, see - the :ref:`Order of Execution ` section. + To learn about why the driver didn't insert the document with the + ``_id`` of ``3``, see the :ref:`Order of Execution ` section. For more information about the methods and classes mentioned in this section, see the `InsertOneModel <{+api+}/apidocs/mongodb-driver-core/com/mongodb/client/model/InsertOneModel.html>`__ API Documentation. @@ -104,22 +102,22 @@ Replace Operation ~~~~~~~~~~~~~~~~~ To perform a replace operation, create a ``ReplaceOneModel`` specifying -a query filter for the document you want to replace with the replacement -document. +a query filter for the document you want to replace and the replacement +document. .. important:: When performing a ``bulkWrite()``, the ``ReplaceOneModel`` cannot - make changes to a document that violate unique index constraints on - the collection, and the model does not replace a document if there - are no matches to your query filter. + make changes that violate unique index constraints on + the collection. Additionally, the model does not perform the replace + operation if there are no matches to the query filter. Example ``````` The following example creates a ``ReplaceOneModel`` to -replace a document where the ``_id`` is "1" with a document that -contains an additional field: +replace a document where the ``_id`` is ``1`` with a document that +contains the additional ``location`` field: .. literalinclude:: /examples/generated/BulkTest.snippet.replace-one.kt :language: kotlin @@ -134,26 +132,25 @@ Update Operation ~~~~~~~~~~~~~~~~ To perform an update operation, create an ``UpdateOneModel`` or an -``UpdateManyModel`` specifying a query filter for documents you want to -update with what the updates are. +``UpdateManyModel`` that specifies a query filter and an update document. The ``UpdateOneModel`` updates the first document that matches your query filter and the ``UpdateManyModel`` updates all the documents that -match your query filter. +match your query filter. .. important:: When performing a ``bulkWrite()``, the ``UpdateOneModel`` and - ``UpdateManyModel`` cannot make changes to a document that violate - unique index constraints on the collection, and the models do not - update any documents if there are no matches to your query filter. + ``UpdateManyModel`` types cannot make changes that violate unique + index constraints on the collection. Additionally, the models do not + perform update operations if there are no matches to the query + filter. Example ``````` -The following example creates an ``UpdateOneModel`` to update -a document where the ``_id`` is "2" to a document that -contains an additional field: +The following example creates an ``UpdateOneModel`` to increment the ``age`` +field by ``1`` in a document where the ``_id`` is ``2``: .. literalinclude:: /examples/generated/BulkTest.snippet.update-one.kt :language: java @@ -169,24 +166,25 @@ Delete Operation ~~~~~~~~~~~~~~~~ To perform a delete operation, create a ``DeleteOneModel`` or a -``DeleteManyModel`` specifying a query filter for documents you want to -delete. +``DeleteManyModel`` that specifies a query filter for documents you want +to delete. The ``DeleteOneModel`` deletes the first document that matches your query filter and the ``DeleteManyModel`` deletes all the documents that -match your query filter. +match your query filter. .. important:: When performing a ``bulkWrite()``, the ``DeleteOneModel`` and - ``DeleteManyModel`` do not delete any documents if there are no matches - to your query filter. + ``DeleteManyModel`` types do not delete any documents if there are no + matches to the query filter. Example ``````` The following example creates a ``DeleteOneModel`` to delete -a document where the ``_id`` is "1": +a document where the ``_id`` is ``1`` and a ``DeleteManyModel`` to delete +documents where the ``age`` value is less than ``30``: .. literalinclude:: /examples/generated/BulkTest.snippet.delete.kt :language: kotlin @@ -204,24 +202,28 @@ Order of Execution The ``bulkWrite()`` method accepts an optional ``BulkWriteOptions`` as a second parameter to specify if you want to execute the bulk operations -as ordered or unordered. +as ordered or unordered. Ordered Execution ~~~~~~~~~~~~~~~~~ By default, the ``bulkWrite()`` method executes bulk operations in -order. This means that the bulk operations execute in the order you -added them to the list until an error occurs, if any. +order. This means that the operations execute in the order you +added them to the list until any error occurs. Example ``````` The following example performs these bulk operations: -- An insert operation for a document where the ``_id`` is "3" -- A replace operation for a document where the ``_id`` is "1" with a document that contains an additional field -- An update operation for a document where the ``_id`` is "3" to a document that contains an additional field -- A delete operation for all documents that contain the field ``x`` with the value "2" +- An insert operation for a document where the ``name`` is + ``"Zaynab Omar"`` and the ``age`` is ``37`` +- A replace operation for a document where the ``_id`` is ``1`` with a new + document that contains the ``location`` field +- An update operation for a document where the ``_id`` is ``6`` to + change the ``name`` field +- A delete operation for all documents that have an ``age`` value + greater than ``50`` .. literalinclude:: /examples/generated/BulkTest.snippet.ordered.kt :language: kotlin @@ -232,38 +234,41 @@ document: .. code-block:: json :copyable: false - { "_id": 2 } + { "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } + { "_id": 8, "name": "Shayla Ray", "age": 20 } + { "_id": 6, "name": "Zaynab Hassan", "age": 37 } Unordered Execution ~~~~~~~~~~~~~~~~~~~ -You can also execute bulk operations in any order by specifying "false" -to the ``order()`` method on ``BulkWriteOptions``. This means that -all the write operations execute regardless of errors and if any errors occur -the bulk operation reports them at the end. +You can also execute bulk operations in any order by passing ``false`` +to the ``ordered()`` method on a ``BulkWriteOptions`` object. This means that +all the write operations execute regardless of errors. If any errors occur, +the driver reports them at the end. -Adding to the preceding example, including the following specifies the bulk -operations to execute in any order: +The following code shows how to execute a bulk operation with no order +of execution: .. literalinclude:: /examples/generated/BulkTest.snippet.unordered.kt :language: kotlin .. note:: - Unordered bulk operations do not guarantee order of execution. The + Unordered bulk operations do not guarantee the order of execution. The order may differ from the way you list them to optimize the runtime. - In the preceding example, if the ``bulkWrite()`` method decided to - perform the insert operation after the update operation, nothing - changes with the update operation because the document does not exist - at that point in time. Your collection then contains the following - documents: + In the preceding example, if the ``bulkWrite()`` method performed the + insert operation after the update operation, the update operation + would not produce changes because the document did not exist + at that point in time. The collection would then contain the following + documents: .. code-block:: json :copyable: false - { "_id": 2 } - { "_id": 3 } + { "_id": 1, "name": "Sandy Kane", "location": "Helena, MT" } + { "_id": 8, "name": "Shayla Ray", "age": 20 } + { "_id": 6, "name": "Zaynab Omar", "age": 37 } For more information about the methods and classes mentioned in this section, see the following API Documentation: @@ -274,14 +279,20 @@ see the following API Documentation: Summary ------- -To perform a bulk operation, you create and pass a list of -``WriteModel`` documents to the ``bulkWrite()`` method. +To perform a bulk operation, create and pass a list of +``WriteModel`` documents to the ``bulkWrite()`` method. + +There are six variations of ``WriteModel``: -There are 6 different ``WriteModel`` documents: ``InsertOneModel``, -``ReplaceOneModel``, ``UpdateOneModel``, ``UpdateManyModel``, -``DeleteOneModel`` and ``DeleteManyModel``. +- ``InsertOneModel`` +- ``ReplaceOneModel`` +- ``UpdateOneModel`` +- ``UpdateManyModel`` +- ``DeleteOneModel`` +- ``DeleteManyModel`` -There are two ways to execute the ``bulkWrite()`` method: +There are two ways to execute the ``bulkWrite()`` method: -- Ordered, which performs the bulk operations in order until an error occurs, if any -- Unordered, which performs all the bulk operations in any order and reports errors at the end, if any +- Ordered, where the driver performs the write operations in order until any error occurs +- Unordered, where the driver performs all the write operations in any order and + reports any errors after the operations complete