diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 4f0b93b6..c9ae5260 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -1,10 +1,11 @@ val kotlin_mongodb_version: String by project plugins { - kotlin("jvm") version "1.8.0" + id("org.jetbrains.kotlin.jvm") version "1.9.25" id("com.google.osdetector") version "1.7.3" application - kotlin("plugin.serialization") version "1.8.21" + id("org.jetbrains.kotlin.plugin.serialization") version "1.9.25" + id("org.jetbrains.kotlin.plugin.scripting") version "1.9.25" } group = "org.mongodb.docs.kotlin" @@ -26,10 +27,11 @@ dependencies { implementation("io.netty:netty-tcnative-boringssl-static:2.0.59.Final:${osdetector.classifier}") implementation("org.xerial.snappy:snappy-java:1.1.10.0") implementation("com.github.luben:zstd-jni:1.5.5-4") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.0") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") implementation("org.mongodb:bson-kotlinx:$kotlin_mongodb_version") - implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0") + implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.6.1") + implementation("org.mongodb:mongodb-driver-kotlin-extensions:$kotlin_mongodb_version") } tasks.test { diff --git a/examples/src/test/kotlin/BuildersDataClassTest.kt b/examples/src/test/kotlin/BuildersDataClassTest.kt new file mode 100644 index 00000000..6fdc67d6 --- /dev/null +++ b/examples/src/test/kotlin/BuildersDataClassTest.kt @@ -0,0 +1,234 @@ +import com.mongodb.client.model.Aggregates.group +import com.mongodb.client.model.Aggregates.limit +import com.mongodb.client.model.Aggregates.sort +import com.mongodb.kotlin.client.coroutine.MongoClient +import config.getConfig +import kotlinx.coroutines.flow.firstOrNull +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.AfterAll +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.TestInstance + +import com.mongodb.kotlin.client.model.Filters.eq +import com.mongodb.kotlin.client.model.Filters.all +import com.mongodb.kotlin.client.model.Indexes +import com.mongodb.kotlin.client.model.Projections.excludeId +import com.mongodb.kotlin.client.model.Projections.fields +import com.mongodb.kotlin.client.model.Projections.include +import com.mongodb.client.model.Sorts.orderBy +import com.mongodb.kotlin.client.model.Accumulators.avg +import com.mongodb.kotlin.client.model.Sorts + +import com.mongodb.kotlin.client.model.Filters.gte +import com.mongodb.kotlin.client.model.Updates.addToSet +import com.mongodb.kotlin.client.model.Updates.combine +import com.mongodb.kotlin.client.model.Updates.max +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +internal class BuildersDataClassTest { + + companion object { + val config = getConfig() + val client = MongoClient.create(config.connectionUri) + val database = client.getDatabase("school") + + @AfterAll + @JvmStatic + fun afterAll() { + runBlocking { + client.close() + } + } + } + + @AfterEach + fun afterEach() { + runBlocking { + database.drop() + } + } + + // :snippet-start: data-class + data class Student( + val name: String, + val teachers: List, + val gradeAverage: Double + ) + // :snippet-end: + + + @Test + fun filtersTest() = runBlocking { + + val collection = database.getCollection("students") + + // :snippet-start: filters-data-class + val student = Student( + "Sandra Nook", + listOf("Alvarez", "Gruber"), + 85.7 + ) + + // Equivalent equality queries + Student::name.eq(student.name) + eq(Student::name, student.name) + Student::name eq student.name // Infix notation + + // Equivalent array queries + all(Student::teachers, student.teachers) + Student::teachers.all(student.teachers) + Student::teachers all student.teachers // Infix notation + // :snippet-end: + + collection.insertOne(student) + val filter = eq(Student::name, student.name) + val result = collection.find(filter).firstOrNull() + Assertions.assertEquals(student, result) + } + + @Test + fun indexesTest() = runBlocking { + + val collection = database.getCollection("students") + + // :snippet-start: indexes-data-class + val ascendingIdx = Indexes.ascending(Student::name) + val descendingIdx = Indexes.descending(Student::teachers) + + val ascIdxName = collection.createIndex(ascendingIdx) + val descIdxName = collection.createIndex(descendingIdx) + // :snippet-end: + + assertEquals("name_1", ascIdxName) + } + + @Test + fun projectionsTest() = runBlocking { + + val collection = database.getCollection("students") + + val student = Student( + "Sandra Nook", + listOf("Alvarez", "Gruber"), + 85.7 + ) + collection.insertOne(student) + + // :snippet-start: projections-data-class + val combinedProj = fields( + include(Student::name, Student::gradeAverage), + excludeId() + ) + + collection.find().projection(combinedProj) + // :snippet-end: + + data class Result(val name: String, val gradeAverage: Double) + val result = collection.find().projection(combinedProj).firstOrNull() + + if (result != null) { + assertEquals(85.7, result.gradeAverage) + } + } + + @Test + fun sortsTest() = runBlocking { + + val collection = database.getCollection("students") + + val student1 = Student( + "Sandra Nook", + listOf("Alvarez", "Gruber"), + 85.7 + ) + val student2 = Student( + "Paolo Sanchez", + listOf("Gruber", "Piselli"), + 89.3 + ) + collection.insertMany(listOf(student1, student2)) + + // :snippet-start: sorts-data-class + val sort = orderBy( + Sorts.descending(Student::gradeAverage), + Sorts.ascending(Student::name) + ) + + collection.find().sort(sort) + // :snippet-end: + + val result = collection.find().sort(sort).firstOrNull() + + if (result != null) { + assertEquals(89.3, result.gradeAverage) + } + } + + @Test + fun updatesTest() = runBlocking { + + val collection = database.getCollection("students") + + val students = listOf( + Student("Sandra Nook", listOf("Alvarez", "Gruber"),85.7), + Student("Paolo Sanchez", listOf("Gruber", "Piselli"),89.3) + ) + collection.insertMany(students) + + // :snippet-start: updates-data-class + val filter = Student::gradeAverage gte 85.0 + val update = combine( + addToSet(Student::teachers, "Soto"), + Student::gradeAverage.max(90.0) + ) + collection.updateMany(filter, update) + // :snippet-end: + + val result = collection.find().firstOrNull() + + if (result != null) { + assertTrue("Soto" in result.teachers) + assertEquals(result.gradeAverage, 90.0) + } + } + + @Test + fun aggregatesTest() = runBlocking { + + val collection = database.getCollection("students") + + val students = listOf( + Student("Sandra Nook", listOf("Alvarez", "Gruber"),85.7), + Student("Paolo Sanchez", listOf("Gruber", "Piselli"),89.3), + Student("Katerina Jakobsen", listOf("Alvarez", "Ender"),97.3), + Student("Emma Frank", listOf("Piselli", "Harbour"),93.4), + Student("Qasim Haq", listOf("Gruber", "Harbour"),80.6) + ) + collection.insertMany(students) + + // :snippet-start: aggregates-data-class + // Data class to store aggregation result + data class Summary ( val average: Double ) + + val pipeline = listOf( + // Sorts grades from high to low + sort(Sorts.descending(Student::gradeAverage)), + // Selects the top 3 students + limit(3), + // Calculates the average of their grades and stores value in a Summary instance + group(null, avg(Summary::average, "\$${Student::gradeAverage.name}")) + ) + + val result = collection.aggregate(pipeline) + // :snippet-end: + + val r = result.firstOrNull() + if (r != null) { + assertEquals(93.33333333333333, r.average) + } + } +} \ No newline at end of file diff --git a/examples/src/test/kotlin/DataClassTest.kt b/examples/src/test/kotlin/DataClassTest.kt index 7a0738d2..7aa3550c 100644 --- a/examples/src/test/kotlin/DataClassTest.kt +++ b/examples/src/test/kotlin/DataClassTest.kt @@ -92,7 +92,7 @@ internal class DataClassTest { .withDocumentClass() .findOneAndUpdate(filter, update, options) - println("Updated document: ${result}") + println("Updated document: $result") // :snippet-end: } diff --git a/source/api-documentation.txt b/source/api-documentation.txt index b17649f0..6a83a4cd 100644 --- a/source/api-documentation.txt +++ b/source/api-documentation.txt @@ -7,16 +7,21 @@ API Documentation :maxdepth: 1 BSON kotlinx.serialization <{+api+}/apidocs/bson-kotlinx/index.html> - Core <{+api+}/apidocs/mongodb-driver-core/index.html> - Kotlin Coroutine Driver <{+api+}/apidocs/mongodb-driver-kotlin-coroutine/index.html> - Kotlin Sync Driver <{+api+}/apidocs/mongodb-driver-kotlin-sync/index.html> + {+language+} Driver Extensions <{+api+}/apidocs/mongodb-driver-kotlin-extensions/index.html> + Driver Core <{+api+}/apidocs/mongodb-driver-core/index.html> + {+language+} Coroutine Driver <{+api+}/apidocs/mongodb-driver-kotlin-coroutine/index.html> + {+language+} Sync Driver <{+api+}/apidocs/mongodb-driver-kotlin-sync/index.html> - `BSON kotlinx.serialization <{+api+}/apidocs/bson-kotlinx/index.html>`__ - classes for encoding and decoding between Kotlin data classes and the BSON data format using :github:`kotlinx.serialization `. -- `Core <{+api+}/apidocs/mongodb-driver-core/index.html>`__ - classes that +- `{+language+} Driver Extensions + <{+api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ - + classes that extend the core builder classes to support :ref:`data + classes `. +- `Driver Core <{+api+}/apidocs/mongodb-driver-core/index.html>`__ - classes that contain essential driver functionality. -- `Kotlin Coroutine Driver <{+api+}/apidocs/mongodb-driver-kotlin-coroutine/index.html>`__ - +- `{+language+} Coroutine Driver <{+api+}/apidocs/mongodb-driver-kotlin-coroutine/index.html>`__ - classes for the current driver API using coroutines. -- `Kotlin Sync Driver <{+api+}/apidocs/mongodb-driver-kotlin-sync/index.html>`__ - +- `{+language+} Sync Driver <{+api+}/apidocs/mongodb-driver-kotlin-sync/index.html>`__ - classes for the current synchronous driver API. diff --git a/source/examples/generated/BuildersDataClassTest.snippet.aggregates-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.aggregates-data-class.kt new file mode 100644 index 00000000..44fb35f9 --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.aggregates-data-class.kt @@ -0,0 +1,13 @@ +// Data class to store aggregation result +data class Summary ( val average: Double ) + +val pipeline = listOf( + // Sorts grades from high to low + sort(Sorts.descending(Student::gradeAverage)), + // Selects the top 3 students + limit(3), + // Calculates the average of their grades and stores value in a Summary instance + group(null, avg(Summary::average, "\$${Student::gradeAverage.name}")) +) + +val result = collection.aggregate(pipeline) diff --git a/source/examples/generated/BuildersDataClassTest.snippet.data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.data-class.kt new file mode 100644 index 00000000..8edca520 --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.data-class.kt @@ -0,0 +1,5 @@ +data class Student( + val name: String, + val teachers: List, + val gradeAverage: Double +) diff --git a/source/examples/generated/BuildersDataClassTest.snippet.filters-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.filters-data-class.kt new file mode 100644 index 00000000..f0c32ebb --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.filters-data-class.kt @@ -0,0 +1,15 @@ +val student = Student( + "Sandra Nook", + listOf("Alvarez", "Gruber"), + 85.7 +) + +// Equivalent equality queries +Student::name.eq(student.name) +eq(Student::name, student.name) +Student::name eq student.name // Infix notation + +// Equivalent array queries +all(Student::teachers, student.teachers) +Student::teachers.all(student.teachers) +Student::teachers all student.teachers // Infix notation diff --git a/source/examples/generated/BuildersDataClassTest.snippet.indexes-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.indexes-data-class.kt new file mode 100644 index 00000000..baeae8ac --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.indexes-data-class.kt @@ -0,0 +1,5 @@ +val ascendingIdx = Indexes.ascending(Student::name) +val descendingIdx = Indexes.descending(Student::teachers) + +val ascIdxName = collection.createIndex(ascendingIdx) +val descIdxName = collection.createIndex(descendingIdx) diff --git a/source/examples/generated/BuildersDataClassTest.snippet.projections-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.projections-data-class.kt new file mode 100644 index 00000000..4da8cc23 --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.projections-data-class.kt @@ -0,0 +1,6 @@ +val combinedProj = fields( + include(Student::name, Student::gradeAverage), + excludeId() +) + +collection.find().projection(combinedProj) diff --git a/source/examples/generated/BuildersDataClassTest.snippet.sorts-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.sorts-data-class.kt new file mode 100644 index 00000000..803372a9 --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.sorts-data-class.kt @@ -0,0 +1,6 @@ +val sort = orderBy( + Sorts.descending(Student::gradeAverage), + Sorts.ascending(Student::name) +) + +collection.find().sort(sort) diff --git a/source/examples/generated/BuildersDataClassTest.snippet.updates-data-class.kt b/source/examples/generated/BuildersDataClassTest.snippet.updates-data-class.kt new file mode 100644 index 00000000..a17d0ee5 --- /dev/null +++ b/source/examples/generated/BuildersDataClassTest.snippet.updates-data-class.kt @@ -0,0 +1,6 @@ +val filter = Student::gradeAverage gte 85.0 +val update = combine( + addToSet(Student::teachers, "Soto"), + Student::gradeAverage.max(90.0) +) +collection.updateMany(filter, update) diff --git a/source/examples/generated/DataClassTest.snippet.retrieve-diff-data-class.kt b/source/examples/generated/DataClassTest.snippet.retrieve-diff-data-class.kt index c37b141e..09e992cd 100644 --- a/source/examples/generated/DataClassTest.snippet.retrieve-diff-data-class.kt +++ b/source/examples/generated/DataClassTest.snippet.retrieve-diff-data-class.kt @@ -14,4 +14,4 @@ val result = collection .withDocumentClass() .findOneAndUpdate(filter, update, options) -println("Updated document: ${result}") +println("Updated document: $result") diff --git a/source/faq.txt b/source/faq.txt index c42bd04d..6443300f 100644 --- a/source/faq.txt +++ b/source/faq.txt @@ -31,56 +31,37 @@ If you have trouble connecting to a MongoDB deployment, see the :ref:`Connection Troubleshooting Guide ` for possible solutions. -How is the Kotlin Driver Different from KMongo? +How is the {+language+} Driver Different from KMongo? ----------------------------------------------- -The Kotlin driver is the official MongoDB driver for Kotlin. It is -developed by the MongoDB team and provides a native API for Kotlin +The {+driver-short+} is the official MongoDB driver for {+language+}. It is +developed by the MongoDB team and provides a native API for {+language+} applications to connect to MongoDB and work with data. It is implemented by wrapping the :driver:`MongoDB Java driver `. .. include:: /includes/kmongo-description.rst -The Kotlin driver was developed in collaboration with the creator of KMongo, +The {+driver-short+} was developed in collaboration with the creator of KMongo, Julien Buret, to give users an officially-supported driver. -The official Kotlin driver and KMongo have generally similar APIs. -Notable similarities between the Kotlin driver and KMongo include: +The official {+driver-short+} and KMongo have generally similar APIs. +Notable similarities between the {+driver-short+} and KMongo include: - Support for synchronous and coroutine-based operations - Support using data classes to represent MongoDB documents -- Support KotlinX serialization -- Support for MongoDB CRUD APIs and aggregation +- Support for KotlinX serialization +- Support for MongoDB CRUD API and aggregation API -Although the official Kotlin driver and KMongo are similar, there are some +Although the official {+driver-short+} and KMongo are similar, there are some key differences: - The official driver does *not* have built-in support for `reactor `__, `rxjava2 `__, `Jackson `__, or `GSON `__. - The official driver does *not* support MongoDB shell commands. -- The official driver supports type-safe queries with the Builders API, - whereas KMongo uses infix functions and property references for - type-safe queries. For more detailed information, see :ref:`Migrate from KMongo `. -What is the Difference Between the Kotlin Driver and the Kotlin SDK? --------------------------------------------------------------------- - -MongoDB supports both mobile and server-side development in Kotlin. If -you are developing a mobile application for Android or Kotlin -Multiplatform (KMP), you can use the :realm:`MongoDB -Atlas Device Kotlin SDK ` to access Atlas App Services and -to manage your Realm data. - -The {+driver-short+} supports server-side development by providing a -complete library for building idiomatic Kotlin applications. You can -learn how to develop asynchronous applications in this documentation for -the Kotlin Coroutine Driver, or you can view the :driver:`Kotlin Sync -Driver documentation ` to learn more about synchronous -programming. - .. _kotlin-faq-connection-pool: How Does Connection Pooling Work in the Kotlin Driver? diff --git a/source/fundamentals/auth.txt b/source/fundamentals/auth.txt index a2372f76..02c41cd9 100644 --- a/source/fundamentals/auth.txt +++ b/source/fundamentals/auth.txt @@ -501,5 +501,5 @@ mechanism: :language: kotlin For additional information on configuring your application to use -certificates as well as TLS/SSL options, see our +certificates and TLS/SSL options, see our :doc:`TLS/SSL guide `. diff --git a/source/fundamentals/builders.txt b/source/fundamentals/builders.txt index 6568aa95..254413a1 100644 --- a/source/fundamentals/builders.txt +++ b/source/fundamentals/builders.txt @@ -12,6 +12,7 @@ Builders Projection Sort Update + Builders & Data Classes .. contents:: On this page :local: @@ -23,46 +24,46 @@ Overview -------- This section includes guides on how to use each of the available -builders, and demonstrates the utility the MongoDB Kotlin driver builder classes -provide. +builders and demonstrates the utility that the {+driver-short+} builder +classes provide. -The Kotlin driver provides classes to simplify the process for developers -to use CRUD operations and the Aggregation API. The static utility methods allow you -to build a query more efficiently. +The {+driver-short+} provides classes to simplify the process of +performing CRUD operations and using the Aggregation API. The static +utility methods allow you to build queries and other kinds of documents +more efficiently. Why Use Builders? ----------------- -Using the builders class, you leverage the power of: +When you use builders classes, you leverage the following products: -- The Kotlin compiler and the IDE to find errors during development -- The IDE for discovery and code completion +- The {+language+} compiler to find errors during development +- The IDE for discovery, debugging, and code completion -When using builders, the Kotlin compiler and the IDE catch errors such as misspelled -operators early on. When using the MongoDB shell or plain Kotlin, you -write operators as strings and get no visual indication of a problem, -pushing these errors to runtime instead of compile time. +When using builders, the {+language+} compiler and the IDE catch errors +such as misspelled operators or missing parameters early on. If you use +the MongoDB shell or plain {+language+} instead, you write operators as +strings and get no visual indication of a problem, which pushes these +errors to runtime instead of compile time. -With the builder classes, you write operators as methods. The IDE -instantly underlines and gives you a red bar on the right indicating -something is wrong. While developing, the IDE also shows you the -methods you can use. It automatically completes your code with -placeholder parameters once you select which method you want to use. +By using builder classes, you can write operators as methods, so that +your IDE instantly indicates whether your code has errors. While +developing, your IDE can also show you methods that you can use and can +complete your code with placeholder parameters. -Scenario --------- +Example Scenario +---------------- -Imagine we want to send a marketing email to all users in our ``users`` -collection with the following criteria: +Suppose you want to send a marketing email to all users in the ``users`` +collection that meet the following criteria: -- Users that identify as ``female`` gender -- Users that are older than ``29`` +- Users in which the value of the ``gender`` field is ``"female"`` +- Users in which the value of the ``age`` field is greater than ``29`` -We only want their email address, so we'll ensure our query doesn't -return data we pay bandwidth costs for but don't need. +You also need your query to return only their email addresses. -The documents in the ``users`` collection are modeled with the following data class -in our application: +The documents in the ``users`` collection are modeled by the following +data class: .. literalinclude:: /examples/generated/BuildersTest.snippet.user-data-class.kt :language: kotlin @@ -70,6 +71,9 @@ in our application: Using the MongoDB Shell ~~~~~~~~~~~~~~~~~~~~~~~ +The following code provides the command you use in the MongoDB Shell to +perform the query: + .. code-block:: js collection.find({ "gender": "female", "age" : { "$gt": 29 }}, { "_id": 0, "email": 1 }) @@ -77,12 +81,22 @@ Using the MongoDB Shell Without Using Builders ~~~~~~~~~~~~~~~~~~~~~~ +The following code provides the find operation you create without +builders in the {+driver-short+}: + .. literalinclude:: /examples/generated/BuildersTest.snippet.no-builders.kt :language: kotlin +In this case, you might easily include an error when writing the +``"\$gt"`` operator in the filter, but your IDE returns the relevant +error only at runtime. + Using Builders ~~~~~~~~~~~~~~ +The following code provides the find operation you create by using +builders in the {+driver-short+}: + .. code-block:: kotlin import com.mongodb.client.model.Filters @@ -110,3 +124,8 @@ Available Builders - :ref:`Sorts ` for building sort criteria. - :ref:`Updates ` for building updates. + +The :ref:`kotlin-builders-data-classes` guide provides examples on +how to use the preceding builders classes directly with data class +properties. This guide might help to make your application more type-safe +and improve {+language+} interoperability. diff --git a/source/fundamentals/builders/aggregates.txt b/source/fundamentals/builders/aggregates.txt index 26af1efa..c8532a32 100644 --- a/source/fundamentals/builders/aggregates.txt +++ b/source/fundamentals/builders/aggregates.txt @@ -58,6 +58,8 @@ modeled by the following ``Movie`` data class for use with the Kotlin driver: .. literalinclude:: /examples/generated/AggregatesBuilderTest.snippet.movie-data-class.kt :language: kotlin +.. include:: /includes/fundamentals/builders-dataclass.rst + Match ----- @@ -534,7 +536,7 @@ to the ``name`` field: .. literalinclude:: /examples/generated/AggregatesBuilderTest.snippet.graph-lookup.kt :language: kotlin -Using ``GraphLookupOptions``, you can specify the depth to recurse as well as +Using ``GraphLookupOptions``, you can specify the depth to recurse and the name of the depth field, if desired. In this example, ``$graphLookup`` will recurse up to two times, and create a field called ``degrees`` with the recursion depth information for every document. diff --git a/source/fundamentals/builders/builders-data-classes.txt b/source/fundamentals/builders/builders-data-classes.txt new file mode 100644 index 00000000..592b9a6c --- /dev/null +++ b/source/fundamentals/builders/builders-data-classes.txt @@ -0,0 +1,249 @@ +.. _kotlin-builders-data-classes: + +============================== +Use Builders with Data Classes +============================== + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: code example, data format, modeling, interoperability + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to use your data class properties +directly with the builder classes available in +the {+driver-short+}. + +The {+driver-short+} implements extensions that allow you to reference +your data class properties when using builder methods instead of using +string field names. You can structure your code in this way to make your +code more type-safe and improve your applications {+language+} +interoperability. + +The extensions library also allows you to construct +queries, update documents, and write other statements by using infix +notation. To learn more about this notation, see `Infix notation +<{+kotlin-docs+}/docs/functions.html#infix-notation>`__ in the +{+language+} reference documentation. + +.. note:: + + This page provides a limited number of code + examples to demonstrate this functionality. To view examples for all + the builder classes, see the :ref:`kotlin-builders-landing` guides. + +Add {+language+} Extensions to Your Project +------------------------------------- + +To implement this functionality, you must add the +``mongodb-driver-kotlin-extensions`` dependency to your dependencies +list. + +Select from the following tabs to see how to add the extension +dependency to your project by using the :guilabel:`Gradle` and +:guilabel:`Maven` package managers: + +.. tabs:: + + .. tab:: + :tabid: Gradle + + If you are using `Gradle `__ to manage your + dependencies, add the following to your ``build.gradle.kts`` dependencies list: + + .. code-block:: kotlin + :caption: build.gradle.kts + + implementation("org.mongodb:mongodb-driver-kotlin-extensions:{+full-version+}") + + .. tab:: + :tabid: Maven + + If you are using `Maven `__ to manage your + dependencies, add the following to your ``pom.xml`` dependencies list: + + .. code-block:: xml + :caption: pom.xml + + + org.mongodb + mongodb-driver-kotlin-extensions + {+full-version+} + + +After you install the extensions dependency, you can use the extension +methods by importing classes and methods from the +``com.mongodb.kotlin.client.model`` path. You can mix usage of these methods and +the standard builder methods in the same application, as shown in the +:ref:`kotlin-data-class-aggregates` example in this guide. + +Builders Examples +----------------- + +This section contains examples that demonstrate how to use data class +properties directly with builder class methods from the extensions +package. + +.. tip:: Data Class Annotations + + When you the extension builder class methods data + classes, the methods respect your data class annotations from the + ``bson-kotlin`` and ``bson-kotlinx`` packages. To learn more about + annotations, see the :ref:`fundamentals-data-class-annotations` + section of the Document Data Format: Data Classes guide and the + :ref:`kotlin-data-class-annotation` section in the {+language+} + Serialization guide. + +Sample Data +~~~~~~~~~~~ + +The examples in this section use documents in the ``students`` +collection that describe students at a school. Documents in the +``students`` collection are modeled by the following {+language+} data +class: + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.data-class.kt + :language: kotlin + +.. _kotlin-data-class-filters: + +Filters +~~~~~~~ + +You can use helpers from the ``Filters`` builders class to query on data +class properties. To learn more about this class, see the +:ref:`filters-builders` guide. + +The following code shows different ways to use ``Filters`` extension +methods to perform queries on the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Filters.eq + import com.mongodb.kotlin.client.model.Filters.all + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.filters-data-class.kt + :language: kotlin + +.. _kotlin-data-class-indexes: + +Indexes +~~~~~~~ + +You can use helpers from the ``Indexes`` builders class to create +indexes on data class properties. To learn more about this class, see the +:ref:`indexes-builders` guide. + +The following code shows different ways to use ``Indexes`` extension +methods to create indexes on the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Indexes.ascending + import com.mongodb.kotlin.client.model.Indexes.descending + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.indexes-data-class.kt + :language: kotlin + +.. _kotlin-data-class-projections: + +Projections +~~~~~~~~~~~ + +You can use helpers from the ``Projections`` builders class to create +projections for data class properties. To learn more about this class, see the +:ref:`projections-builders` guide. + +The following code shows how to use ``Projections`` extension +methods to create a projection on the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Projections.excludeId + import com.mongodb.kotlin.client.model.Projections.fields + import com.mongodb.kotlin.client.model.Projections.include + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.projections-data-class.kt + :language: kotlin + +.. _kotlin-data-class-sorts: + +Sorts +~~~~~ + +You can use helpers from the ``Sorts`` builders class to sort +on your data class properties. To learn more about this class, see the +:ref:`sorts-builders` guide. + +The following code shows how to use ``Sorts`` extension +methods to create different sorts on the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.client.model.Sorts.orderBy + import com.mongodb.kotlin.client.model.Sorts + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.sorts-data-class.kt + :language: kotlin + +.. _kotlin-data-class-updates: + +Updates +~~~~~~~ + +You can use helpers from the ``Updates`` builders class to perform +updates by using your data class properties. To learn more about this +class, see the :ref:`updates-builders` guide. + +The following code shows how to use ``Sorts`` extension +methods to create different sorts on the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Filters.gte + import com.mongodb.kotlin.client.model.Updates.addToSet + import com.mongodb.kotlin.client.model.Updates.combine + import com.mongodb.kotlin.client.model.Updates.max + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.updates-data-class.kt + :language: kotlin + +.. _kotlin-data-class-aggregates: + +Aggregates +~~~~~~~~~~ + +You can use helpers from the ``Aggregates`` and ``Accumulators`` +builders classes to perform aggregations by using you data class +properties. To learn more about these classes, see the +:ref:`aggregates-builders` guide. + +The following code shows how to use ``Accumulators`` extension +methods and ``Aggregates`` helper methods to perform an aggregation on +the ``Student`` data class: + +.. code-block:: kotlin + + import com.mongodb.client.model.Aggregates.group + import com.mongodb.client.model.Aggregates.limit + import com.mongodb.client.model.Aggregates.sort + import com.mongodb.kotlin.client.model.Accumulators.avg + +.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.aggregates-data-class.kt + :language: kotlin + +API Documentation +----------------- + +- `{+driver-short+} Extensions + <{+api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ diff --git a/source/fundamentals/builders/filters.txt b/source/fundamentals/builders/filters.txt index aa585c0d..a879fd4b 100644 --- a/source/fundamentals/builders/filters.txt +++ b/source/fundamentals/builders/filters.txt @@ -62,7 +62,8 @@ type, which you can pass to any method that expects a query filter. import com.mongodb.client.model.Filters.* -Most of the ``Filter`` examples in this guide use the following sample collection ``paints``: +Most of the ``Filters`` examples in this guide use the following sample +collection ``paints``: .. code-block:: json @@ -81,6 +82,8 @@ with the Kotlin driver: .. literalinclude:: /examples/generated/FiltersBuildersTest.snippet.paint-order-data-class.kt :language: kotlin +.. include:: /includes/fundamentals/builders-dataclass.rst + .. _comparison: Comparison diff --git a/source/fundamentals/builders/indexes.txt b/source/fundamentals/builders/indexes.txt index 425f62dd..a3e05f82 100644 --- a/source/fundamentals/builders/indexes.txt +++ b/source/fundamentals/builders/indexes.txt @@ -45,6 +45,8 @@ instance, which you can pass to import com.mongodb.client.model.Indexes.* +.. include:: /includes/fundamentals/builders-dataclass.rst + .. _ascending-indexes: Ascending Indexes diff --git a/source/fundamentals/builders/projections.txt b/source/fundamentals/builders/projections.txt index fa62ccac..82316de6 100644 --- a/source/fundamentals/builders/projections.txt +++ b/source/fundamentals/builders/projections.txt @@ -40,7 +40,6 @@ to any method that expects a projection. import com.mongodb.client.model.Projections.* - Sample Documents and Examples ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -96,6 +95,8 @@ The following data class is used to represent the documents in the collection: .. literalinclude:: /examples/generated/ProjectionsBuildersTest.snippet.example-data-class.kt :language: kotlin +.. include:: /includes/fundamentals/builders-dataclass.rst + Projection Operations --------------------- diff --git a/source/fundamentals/builders/sort.txt b/source/fundamentals/builders/sort.txt index 4fd07f02..6d9a41ec 100644 --- a/source/fundamentals/builders/sort.txt +++ b/source/fundamentals/builders/sort.txt @@ -53,6 +53,8 @@ This data is modeled with the following Kotlin data class: .. literalinclude:: /examples/generated/SortTest.snippet.sort-data-model.kt :language: kotlin +.. include:: /includes/fundamentals/builders-dataclass.rst + The Sorts Class --------------- diff --git a/source/fundamentals/builders/updates.txt b/source/fundamentals/builders/updates.txt index c23c1d12..8ebcf85d 100644 --- a/source/fundamentals/builders/updates.txt +++ b/source/fundamentals/builders/updates.txt @@ -69,6 +69,8 @@ This example is modeled by the following data class unless otherwise noted: .. literalinclude:: /examples/generated/UpdatesBuildersTest.snippet.example-data-class.kt :language: kotlin +.. include:: /includes/fundamentals/builders-dataclass.rst + .. _field_updates: Field Updates diff --git a/source/fundamentals/data-formats/document-data-format-data-class.txt b/source/fundamentals/data-formats/document-data-format-data-class.txt index aa47b367..c20d3a77 100644 --- a/source/fundamentals/data-formats/document-data-format-data-class.txt +++ b/source/fundamentals/data-formats/document-data-format-data-class.txt @@ -14,12 +14,12 @@ Overview -------- In this guide, you can learn how to store and retrieve data in the -{+driver-long+} using **Kotlin data classes**. +{+driver-long+} by using **{+language+} data classes**. Serialize and Deserialize a Data Class -------------------------------------- -The driver natively supports encoding and decoding Kotlin data classes for +The driver natively supports encoding and decoding {+language+} data classes for MongoDB read and write operations using the **default codec registry**. The default codec registry is a collection of classes called **codecs** that define how to encode and decode Kotlin and Java types. @@ -60,6 +60,8 @@ as shown in the following code: DataStorage(productName=tape, capacity=5.0) +.. include:: /includes/fundamentals/builders-dataclass.rst + You specify a class for documents returned from a collection, even if it is different than the class you specified when retrieving the collection. @@ -105,7 +107,7 @@ You can use the following annotations on data classes: - Description * - ``BsonId`` - - Marks a property to serialize as the _id property. + - Marks a property to serialize as the ``_id`` property. * - ``BsonProperty`` - Specifies a custom document field name when converting the data class diff --git a/source/fundamentals/data-formats/documents.txt b/source/fundamentals/data-formats/documents.txt index c19af974..339eb475 100644 --- a/source/fundamentals/data-formats/documents.txt +++ b/source/fundamentals/data-formats/documents.txt @@ -18,8 +18,8 @@ MongoDB Kotlin driver. A MongoDB document is a data structure that contains key/value fields in binary JSON (BSON) format. You can use documents and the data they contain -in their fields to store data as well as issue commands or queries in -MongoDB. +in their fields to store data, and you can use them to issue commands or +queries in MongoDB. For more information on the terminology, structure, and limitations of documents, read our page on :manual:`Documents ` in the MongoDB manual. diff --git a/source/fundamentals/data-formats/serialization.txt b/source/fundamentals/data-formats/serialization.txt index 5be4d17b..16ca363a 100644 --- a/source/fundamentals/data-formats/serialization.txt +++ b/source/fundamentals/data-formats/serialization.txt @@ -54,7 +54,7 @@ The {+driver-short+} supports: - All Kotlin types that are supported by the Kotlin serialization library - All available :manual:`BSON types ` -Add Kotlin Serialization to Your Project +Add {+language+} Serialization to Your Project ---------------------------------------- Support for serialization in the {+driver-short+} depends on the official `Kotlin diff --git a/source/includes/fundamentals/builders-dataclass.rst b/source/includes/fundamentals/builders-dataclass.rst new file mode 100644 index 00000000..2bf302f3 --- /dev/null +++ b/source/includes/fundamentals/builders-dataclass.rst @@ -0,0 +1,6 @@ +.. tip:: Builder Methods and Data Class Properties + + You can use the methods from builder classes directly with data + class properties by adding the optional {+driver-short+} extensions + dependency to your application. To learn more and view examples, see + the :ref:`kotlin-builders-data-classes` guide. diff --git a/source/index.txt b/source/index.txt index 84084892..745dde13 100644 --- a/source/index.txt +++ b/source/index.txt @@ -29,15 +29,11 @@ Download the driver by using `Maven `__ or `Gradle `__, or set up a runnable project by following our Quick Start guide. -.. tip:: Other Kotlin Platforms for MongoDB +.. tip:: {+language+} Sync Driver If your Kotlin application requires synchronous processing, use the :driver:`Sync Driver `, which uses synchronous operations to make blocking calls to MongoDB. - - If you are developing an Android or Kotlin Multiplatform (KMP) - application, you can use the :realm:`MongoDB Atlas Device Kotlin SDK ` - to access Atlas App Services and to manage your Realm data. Quick Start ----------- diff --git a/source/migrate-kmongo.txt b/source/migrate-kmongo.txt index 8b8938be..fbf1f252 100644 --- a/source/migrate-kmongo.txt +++ b/source/migrate-kmongo.txt @@ -4,6 +4,14 @@ Migrate from KMongo =================== +.. facet:: + :name: genre + :values: tutorial + +.. meta:: + :description: Learn how to migrate your application from KMongo to the official MongoDB Kotlin driver. + :keywords: code example, adapt, syntax + .. contents:: On this page :local: :backlinks: none @@ -15,36 +23,37 @@ Overview -------- This page contains a high-level comparison of most of the ways the official -MongoDB Kotlin and the community-developed KMongo driver differ. +{+driver-long+} and the community-developed KMongo driver differ. You can use this page to identify the changes you need to make to migrate from -the deprecated KMongo driver to the official MongoDB Kotlin driver. +the deprecated KMongo driver to the official {+driver-long+}. .. include:: /includes/kmongo-description.rst -The MongoDB Kotlin driver is the officially supported and maintained MongoDB driver for -Kotlin. It is developed by the MongoDB team. +The {+driver-long+} is the officially supported and maintained MongoDB driver for +{+language+}. It is developed by the MongoDB team. -Although both drivers :ref:`support synchronous and asynchronous operations `, -the examples on this page will use asynchronous coroutine-based operations. +Although both drivers :ref:`support synchronous and asynchronous +operations `, the examples on this page will +use asynchronous coroutine-based operations. Connect to MongoDB Cluster -------------------------- Both drivers let you connect to and communicate with MongoDB clusters from a -Kotlin application. +{+language+} application. .. tabs:: .. tab:: :tabid: {+driver-long+} - To connect to a MongoDB cluster using the MongoDB Kotlin driver: + To connect to a MongoDB cluster using the {+driver-long+}: .. code-block:: kotlin import com.mongodb.kotlin.client.coroutine.MongoClient - data class Jedi(val name: String, val age: Int) + data class Jedi(val name: String, val age: Int) // Replace the placeholder with your MongoDB deployment's connection string val uri = CONNECTION_STRING_URI_PLACEHOLDER @@ -77,7 +86,7 @@ Kotlin application. // Get a collection of documents of type Jedi val col = database.getCollection() - Unlike the MongoDB Kotlin driver, KMongo allows the collection name to be + Unlike the {+driver-long+}, KMongo allows the collection name to be inferred from the data class name. CRUD and Aggregation @@ -86,51 +95,93 @@ CRUD and Aggregation Both drivers provide support for all MongoDB CRUD APIs and aggregation operations. +.. tip:: + + If you are accustomed to constructing query filters by using the + infix notation available in KMongo, you can also use this notation to + create filters in the official {+driver-short+} by using extension + methods from the ``mongodb-driver-kotlin-extensions`` package. Select + the :guilabel:`Kotlin Driver Extensions` tab to view an example that + uses this query syntax in the {+driver-short+}. + .. tabs:: .. tab:: :tabid: {+driver-long+} - The MongoDB Kotlin driver also provides functions for all basic CRUD operations: + The {+driver-long+} also provides functions for all basic CRUD operations: .. code-block:: kotlin - // Insert a document - val jedi =a Jedi("Luke Skywalker", 19) - collection.insertOne(jedi) + // Insert a document + val jedi = Jedi("Luke Skywalker", 19) + collection.insertOne(jedi) - // Find a document - val luke = collection.find(Jedi::name.name, "Luke Skywalker") - val jedis = collection.find(lt(Jedi::age.name, 30)).toList() + // Find a document + val luke = collection.find(Jedi::name.name, "Luke Skywalker") + val jedis = collection.find(lt(Jedi::age.name, 30)).toList() - // Update a document - val filter = Filters.eq(Jedi::name.name, "Luke Skywalker") - val update = Updates.set(Jedi::age.name, 20) - collection.updateOne(filter, update) + // Update a document + val filter = Filters.eq(Jedi::name.name, "Luke Skywalker") + val update = Updates.set(Jedi::age.name, 20) + collection.updateOne(filter, update) - // Delete a document - val filter = Filters.eq(Jedi::name.name, "Luke Skywalker") - collection.deleteOne(filter) + // Delete a document + val filter = Filters.eq(Jedi::name.name, "Luke Skywalker") + collection.deleteOne(filter) - Aggregation pipelines can be built using the ``aggregate`` method and the - ``pipeline`` function: + You can build aggregation pipelines by using the ``aggregate()`` + method and the ``pipeline`` function: .. code-block:: kotlin - data class Results(val avgAge: Double) + data class Results(val avgAge: Double) - val resultsFlow = collection.aggregate( - listOf( - Aggregates.match(Filters.ne(Jedi::name.name, "Luke Skywalker")), - Aggregates.group("\$${Jedi::name.name}", - Accumulators.avg("avgAge", "\$${Jedi::age.name}")) - ) - ) - resultsFlow.collect { println(it) } + val resultsFlow = collection.aggregate( + listOf( + Aggregates.match(Filters.ne(Jedi::name.name, "Luke Skywalker")), + Aggregates.group("\$${Jedi::name.name}", + Accumulators.avg("avgAge", "\$${Jedi::age.name}")) + ) + ) + resultsFlow.collect { println(it) } See the :ref:`CRUD Operations ` and :ref:`Aggregation ` documentation for more information. - + + .. tab:: + :tabid: Kotlin Driver Extensions + + You can use the Builders API from the + ``mongodb-driver-kotlin-extensions`` library to create query + filters and aggregation pipeline stages directly using data class + properties. This library also allows you to create queries by + using infix notation: + + .. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Filters.eq + import com.mongodb.kotlin.client.model.Filters.lt + import com.mongodb.kotlin.client.model.Updates.set + + data class Jedi(val name: String, val age: Int) + + // Find documents + val luke = collection.find(Jedi::name eq "Luke Skywalker") + val jedis = collection.find(Jedi::age lt 30)).toList() + + // Update a document + val filter = Jedi::name eq "Luke Skywalker" + val update = Jedi::age.name set 20 + collection.updateOne(filter, update) + + // Delete a document + val filter = Jedi::name eq "Luke Skywalker" + collection.deleteOne(filter) + + To learn more and view examples that use all the builder + classes, see the :ref:`kotlin-builders-data-classes` guide. + .. tab:: :tabid: KMongo @@ -173,44 +224,84 @@ Construct Queries Both drivers provide support for type-safe queries using property references. +.. tip:: + + If you are accustomed to constructing query filters by using the + infix notation available in KMongo, you can also use this notation to + create filters in the official {+driver-short+} by using extension + methods from the ``mongodb-driver-kotlin-extensions`` package. Select + the :guilabel:`Kotlin Driver Extensions` tab to view an example that + uses this query syntax in the {+driver-short+}. + .. tabs:: .. tab:: :tabid: {+driver-long+} - The MongoDB Kotlin driver uses the Builders API to construct queries. + The {+driver-long+} uses the Builders API to construct queries. Alternatively, you can use the ``Document`` class. .. code-block:: kotlin - data class Person(val name: String, val email: String, val gender: String, val age: Int) - data class Results(val email: String) - - val collection = database.getCollection("people") - - // Using Builders - val filter = and(eq("gender", "female"), gt("age", 29)) - val projection = fields(excludeId(), include("email")) - val results = collection.find(filter).projection(projection) - - // Using Document class - val filter = Document().append("gender", "female").append("age", Document().append("\$gt", 29)) - val projection = Document().append("_id", 0).append("email", 1) - val results = collection.find(filter).projection(projection) - - To map a KMongo string query to the Kotlin driver, you can use the ``JsonObject`` class. + data class Person(val name: String, val email: String, val gender: String, val age: Int) + data class Results(val email: String) + + val collection = database.getCollection("people") + + // Using Builders + val filter = and(eq("gender", "female"), gt("age", 29)) + val projection = fields(excludeId(), include("email")) + val results = collection.find(filter).projection(projection) + + // Using Document class + val filter = Document().append("gender", "female").append("age", Document().append("\$gt", 29)) + val projection = Document().append("_id", 0).append("email", 1) + val results = collection.find(filter).projection(projection) + + To map a KMongo string query to the {+driver-short+}, you can use the ``JsonObject`` class. .. code-block:: kotlin val query = JsonObject("{\"name\": \"Gabriel Garc\\u00eda M\\u00e1rquez\"}") val jsonResult = collection.find(query).firstOrNull() - For more information, see the following Kotlin driver documentation: + For more information, see the following {+driver-short+} documentation: - :ref:`Builders ` - :ref:`Documents ` guide - `JsonObject <{+api+}/apidocs/bson/org/bson/json/JsonObject.html>`__ API Documentation - + + .. tab:: + :tabid: Kotlin Driver Extensions + + You can use the Builders API from the + ``mongodb-driver-kotlin-extensions`` library to construct queries + directly on data class properties. This library also allows you to + create queries by using infix notation: + + .. code-block:: kotlin + + import com.mongodb.kotlin.client.model.Filters.eq + import com.mongodb.kotlin.client.model.Filters.and + import com.mongodb.kotlin.client.model.Filters.gt + import com.mongodb.kotlin.client.model.Projections.excludeId + import com.mongodb.kotlin.client.model.Projections.fields + import com.mongodb.kotlin.client.model.Projections.include + + data class Person(val name: String, val gender: String, val age: Int) + data class Result(val name: String) + + val collection = database.getCollection("people") + + // Infix Notation Query + val filter = (Person::gender eq "female") and (Person::age gt 29)) + val projection = fields(excludeId(), include(Person::name)) + + val results = collection.find(filter).projection(projection) + + To learn more and view examples that use all the builder + classes, see the :ref:`kotlin-builders-data-classes` guide. + .. tab:: :tabid: KMongo @@ -253,9 +344,10 @@ Both drivers provide support for type-safe queries using property references. Data Typing ----------- -Both drivers support the use of Kotlin data classes as well as the ``Document`` class to -model the data stored in a MongoDB collection. The ``Document`` -class lets you model data represented in a MongoDB collection in a flexible format. +Both drivers support the use of {+language+} data classes and the +``Document`` class to model the data stored in a MongoDB collection. The +``Document`` class lets you model data represented in a MongoDB +collection in a flexible format. .. tabs:: @@ -263,7 +355,7 @@ class lets you model data represented in a MongoDB collection in a flexible form :tabid: {+driver-long+} You can use data classes and ``Document`` classes to model data with the - MongoDB Kotlin driver: + {+driver-long+}: .. code-block:: kotlin @@ -302,17 +394,17 @@ Data Serialization ------------------ Both drivers provide support for serializing and deserializing data objects -in Kotlin to and from BSON. +in {+language+} to and from BSON. .. tabs:: .. tab:: :tabid: {+driver-long+} - You can serialize data classes in the Kotlin driver using both automatic - data class codecs as well as the ``kotlinx.serialization`` library. The + You can serialize data classes in the {+driver-short+} using both automatic + data class codecs and the ``kotlinx.serialization`` library. The driver provides an efficient ``Bson`` serializer that handles the - serialization of Kotlin objects to BSON data. + serialization of {+language+} objects to BSON data. .. code-block:: kotlin @@ -326,7 +418,7 @@ in Kotlin to and from BSON. val manufacturer: String = "Acme" // Use instead of @BsonProperty ) - To learn more, see the :ref:`Kotlin Serialization ` + To learn more, see the :ref:`{+language+} Serialization ` documentation. If you use the ``Document`` class to represent your collection, you can @@ -381,9 +473,9 @@ Both drivers support synchronous and asynchronous operations. .. tab:: :tabid: {+driver-long+} - The MongoDB Kotlin driver also has separate libraries for synchronous and - asynchronous operations. However, the Kotlin driver only has built-in support - for coroutines as an asynchronous paradigm. The MongoDB Kotlin driver does not + The {+driver-long+} also has separate libraries for synchronous and + asynchronous operations. However, the {+driver-short+} only has built-in support + for coroutines as an asynchronous paradigm. The {+driver-long+} does not currently provide support for other asynchronous paradigms such as Reactive Streams, Reactor, or RxJava2. @@ -418,7 +510,7 @@ Both drivers support synchronous and asynchronous operations. val collection = database.getCollection("jedi") // Synchronous operations - val jedi =a Jedi("Luke Skywalker", 19) + val jedi = Jedi("Luke Skywalker", 19) collection.insertOne(jedi) To write asynchronous coroutine code: @@ -437,7 +529,7 @@ Both drivers support synchronous and asynchronous operations. runBlocking { // Async operations - val jedi =a Jedi("Luke Skywalker", 19) + val jedi = Jedi("Luke Skywalker", 19) collection.insertOne(jedi) } @@ -514,5 +606,5 @@ What Next? ---------- Now that you have learned about the differences between KMongo and the MongoDB -Kotlin driver, see the :ref:`Quick Start ` to get -started using the KMongo Kotlin driver. +{+driver-short+}, see the :ref:`Quick Start ` to get +started using the KMongo {+driver-short+}. diff --git a/source/usage-examples/updateMany.txt b/source/usage-examples/updateMany.txt index 339cf083..ace9a0fb 100644 --- a/source/usage-examples/updateMany.txt +++ b/source/usage-examples/updateMany.txt @@ -56,7 +56,7 @@ bottom of this page. Example ------- -In this example, we use a ``Filter`` builder to filter our query for +In this example, we use a ``Filters`` builder to filter our query for movies in the genre "Frequently Discussed". Next, we update documents that match our query in the ``movies`` collection of the diff --git a/source/usage-examples/updateOne.txt b/source/usage-examples/updateOne.txt index 6cd6b11c..471a7a40 100644 --- a/source/usage-examples/updateOne.txt +++ b/source/usage-examples/updateOne.txt @@ -54,7 +54,7 @@ bottom of this page. Example ------- -In this example, we use a ``Filter`` builder to query the collection for +In this example, we use a ``Filters`` builder to query the collection for a movie with the title "Cool Runnings 2". Next, we perform the following updates to the first match for our query diff --git a/source/whats-new.txt b/source/whats-new.txt index 202a7fbf..94c617ac 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -43,6 +43,12 @@ improvements, and fixes: the :ref:`kotlin-fundamentals-change-document` and :ref:`kotlin-fundamentals-bulkwrite` guides +- Support for using builders class methods directly with data class + properties. To learn more, see the :ref:`kotlin-builders-data-classes` + guide. This functionality is supported by the `{+driver-short+} + Extensions package <{+api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ + published with this release. + - Implements a *client* bulk write API that allows you to perform write operations on multiple databases and collections in the same call. To learn more about this feature, see the :ref:`kotlin-client-bulk-write`