Skip to content

DOCSP-46772: sort option for client bw - updateone & replaceone #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 74 additions & 23 deletions examples/src/test/kotlin/ClientBulkTest.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import com.mongodb.MongoNamespace
import com.mongodb.client.model.Filters
import com.mongodb.client.model.Sorts
import com.mongodb.client.model.Updates
import com.mongodb.client.model.bulk.ClientBulkWriteOptions
import com.mongodb.client.model.bulk.ClientNamespacedWriteModel
import com.mongodb.client.model.bulk.ClientReplaceOneOptions
import com.mongodb.client.model.bulk.ClientUpdateOneOptions
import com.mongodb.kotlin.client.coroutine.MongoClient
import config.getConfig
import kotlinx.coroutines.runBlocking
Expand All @@ -19,11 +23,14 @@ internal class ClientBulkTest {
data class Person(
@BsonId val id: Int,
val name: String,
val age: Int? = null,
)

data class Object(
@BsonId val id: Int,
val type: String,
val category: String? = null,
val manufacturer: String? = null,
)
// :snippet-end:

Expand All @@ -40,7 +47,14 @@ internal class ClientBulkTest {
fun beforeAll() {
runBlocking {
personCollection.insertOne(Person(1, "Sandy King"))
objectCollection.insertOne(Object(1, "artist easel"))
personCollection.insertOne(Person(1, "Freya Polk", 34))
objectCollection.insertMany(
listOf(
Object(1, "artist easel"),
Object(2, "keyboard", "electronic"),
Object(3, "blender", "electronic"),
)
)
}
}

Expand All @@ -62,18 +76,20 @@ internal class ClientBulkTest {
// :snippet-start: insert-models
val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()

docsToInsert.add(ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "people"),
Person(2, "Julia Smith")
)
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "people"),
Person(2, "Julia Smith")
)
)

docsToInsert.add(ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "objects"),
Object(2, "washing machine")
)
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "objects"),
Object(2, "washing machine")
)
)

val clientBulkResult = client.bulkWrite(docsToInsert)
Expand All @@ -84,25 +100,60 @@ internal class ClientBulkTest {
assertEquals(2, personCollection.countDocuments())
}


// Ignoring tests because successful completion of
// writes is blocked on https://jira.mongodb.org/browse/CLOUDP-288992
@Ignore
fun updateOperationTest() = runBlocking {
// :snippet-start: update-models
val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()

docsToInsert.add(
ClientNamespacedWriteModel
.updateOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::name.name, "Freya Polk"),
Updates.inc(Person::age.name, 1)
)
)

docsToInsert.add(
ClientNamespacedWriteModel
.updateMany(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::category.name, "electronic"),
Updates.set(Object::manufacturer.name, "Premium Technologies")
)
)

val clientBulkResult = client.bulkWrite(docsToInsert)
// :snippet-end:

// Junit test for the above code
assertEquals(3, clientBulkResult.modifiedCount)
}

@Ignore
fun replaceOperationTest() = runBlocking {
// :snippet-start: replace-models
val docsReplacements = mutableListOf<ClientNamespacedWriteModel>()

docsReplacements.add(ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::id.name, 1),
Person(1, "Frederic Hilbert")
)
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::id.name, 1),
Person(1, "Frederic Hilbert")
)
)

docsReplacements.add(ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::id.name, 1),
Object(1, "ironing board")
)
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::id.name, 1),
Object(1, "ironing board")
)
)

val clientBulkResult = client.bulkWrite(docsReplacements)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
data class Person(
@BsonId val id: Int,
val name: String,
val age: Int? = null,
)

data class Object(
@BsonId val id: Int,
val type: String,
val category: String? = null,
val manufacturer: String? = null,
)
22 changes: 12 additions & 10 deletions source/examples/generated/ClientBulkTest.snippet.insert-models.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()

docsToInsert.add(ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "people"),
Person(2, "Julia Smith")
)
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "people"),
Person(2, "Julia Smith")
)
)

docsToInsert.add(ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "objects"),
Object(2, "washing machine")
)
docsToInsert.add(
ClientNamespacedWriteModel
.insertOne(
MongoNamespace("sample_db", "objects"),
Object(2, "washing machine")
)
)

val clientBulkResult = client.bulkWrite(docsToInsert)
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
val docsReplacements = mutableListOf<ClientNamespacedWriteModel>()

docsReplacements.add(ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::id.name, 1),
Person(1, "Frederic Hilbert")
)
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::id.name, 1),
Person(1, "Frederic Hilbert")
)
)

docsReplacements.add(ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::id.name, 1),
Object(1, "ironing board")
)
docsReplacements.add(
ClientNamespacedWriteModel
.replaceOne(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::id.name, 1),
Object(1, "ironing board")
)
)

val clientBulkResult = client.bulkWrite(docsReplacements)
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
val docsToInsert = mutableListOf<ClientNamespacedWriteModel>()

docsToInsert.add(
ClientNamespacedWriteModel
.updateOne(
MongoNamespace("sample_db", "people"),
Filters.eq(Person::name.name, "Freya Polk"),
Updates.inc(Person::age.name, 1)
)
)

docsToInsert.add(
ClientNamespacedWriteModel
.updateMany(
MongoNamespace("sample_db", "objects"),
Filters.eq(Object::category.name, "electronic"),
Updates.set(Object::manufacturer.name, "Premium Technologies")
)
)

val clientBulkResult = client.bulkWrite(docsToInsert)
53 changes: 49 additions & 4 deletions source/fundamentals/crud/write-operations/bulk.txt
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ contains the additional ``location`` field:
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 driver performs the replace
an order to matched documents before the server performs the replace
operation, as shown in the following code:

.. literalinclude:: /examples/generated/BulkTest.snippet.replace-model-options.kt
Expand Down Expand Up @@ -202,7 +202,7 @@ field by ``1`` in a document where the ``_id`` is ``2``:
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 driver performs the update
an order to matched documents before the server performs the update
operation, as shown in the following code:

.. literalinclude:: /examples/generated/BulkTest.snippet.update-model-options.kt
Expand Down Expand Up @@ -466,20 +466,65 @@ each write operation applies to.
.. literalinclude:: /examples/generated/ClientBulkTest.snippet.insert-models.kt
:language: kotlin

.. _kotlin-client-bulk-write-update:

Update Operation
~~~~~~~~~~~~~~~~

The following example shows how to use the ``bulkWrite()`` method to update
existing documents in the ``db.people`` and ``db.objects`` collections:

.. literalinclude:: /examples/generated/ClientBulkTest.snippet.update-models.kt
:language: kotlin

This example increments the value of the ``age`` field by ``1`` in the
document that has a ``name`` value of ``"Freya Polk"`` in the ``people``
collection. It also sets the value of the ``manufacturer`` field to
``"Premium Technologies"`` in all documents that have a ``category``
value of ``"electronic"`` in the ``objects`` 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
<{+api+}/apidocs/mongodb-driver-core/com/mongodb/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-client-bulk-write-replace:

Replace Operation
~~~~~~~~~~~~~~~~~

The following example shows how to use the ``bulkWrite()`` method to replace
existing documents in the ``sample_db.people`` and ``sample_db.things`` collections.
existing documents in the ``sample_db.people`` and ``sample_db.objects`` collections.

.. literalinclude:: /examples/generated/ClientBulkTest.snippet.replace-models.kt
:language: kotlin

After this example runs successfully, the document that has an ``_id`` value of ``1``
in the ``people`` collection is replaced with a new document. The document in
the ``things`` collection that has an ``_id`` value of ``1``
the ``objects`` collection that has an ``_id`` value of ``1``
is 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
<{+api+}/apidocs/mongodb-driver-core/com/mongodb/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"))

.. _kotlin-client-bulk-write-options:

Bulk Write Options
Expand Down
7 changes: 7 additions & 0 deletions source/fundamentals/transactions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,13 @@ and commit changes to existing documents:

.. sharedinclude:: dbx/transactions-parallelism.rst

.. replacement:: driver-specific-content

If you're using {+mdb-server+} v8.0 or later, you can perform
write operations on multiple namespaces within a single
transaction by using bulk write operations. To learn more, see the
:ref:`kotlin-fundamentals-bulkwrite` guide.

Additional Information
----------------------

Expand Down
17 changes: 17 additions & 0 deletions source/whats-new.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ What's New

Learn what's new in:

* :ref:`Version 5.4 <kotlin-coroutine-version-5.4>`
* :ref:`Version 5.3 <kotlin-coroutine-version-5.3>`
* :ref:`Version 5.2 <kotlin-coroutine-version-5.2>`
* :ref:`Version 5.1.3 <kotlin-coroutine-version-5.1.3>`
Expand All @@ -22,6 +23,22 @@ Learn what's new in:
* :ref:`Version 4.11 <version-4.11>`
* :ref:`Version 4.10 <version-4.10>`

.. _kotlin-coroutine-version-5.4:

What's New in 5.4
-----------------

The 5.4 driver release includes the following changes, fixes,
and features:

.. sharedinclude:: dbx/jvm/v5.4-wn-items.rst

.. replacement:: sort-option-link

the :ref:`kotlin-client-bulk-write-update` and
:ref:`kotlin-client-bulk-write-replace` sections of the Bulk
Operations guide

.. _kotlin-coroutine-version-5.3:

What's New in 5.3
Expand Down
Loading