From c6352b4b0674a312643469f6bfdc0ca45daa5436 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 24 Jan 2025 13:51:33 -0500 Subject: [PATCH 1/4] DOCSP-36218: filters with dataclass properties WIP --- source/api.txt | 26 ++ source/builders.txt | 22 +- source/builders/builders-data-classes.txt | 249 ++++++++++++++++++ source/data-formats.txt | 5 +- .../data-formats/data-format-data-class.txt | 225 ++++++++++++++++ .../data-formats/builders-dataclass.rst | 6 + source/includes/data-formats/data-class.kt | 114 ++++++++ source/index.txt | 10 +- 8 files changed, 644 insertions(+), 13 deletions(-) create mode 100644 source/api.txt create mode 100644 source/builders/builders-data-classes.txt create mode 100644 source/data-formats/data-format-data-class.txt create mode 100644 source/includes/data-formats/builders-dataclass.rst create mode 100644 source/includes/data-formats/data-class.kt diff --git a/source/api.txt b/source/api.txt new file mode 100644 index 00000000..1296bdf8 --- /dev/null +++ b/source/api.txt @@ -0,0 +1,26 @@ +.. _kotlin-sync-api-docs: + +================= +API Documentation +================= + +.. toctree:: + :titlesonly: + :maxdepth: 1 + + {+language+} Sync Driver <{+java-api+}/apidocs/mongodb-driver-kotlin-sync/index.html> + BSON kotlinx.serialization <{+java-api+}/apidocs/bson-kotlinx/index.html> + {+language+} Driver Extensions <{+java-api+}/apidocs/mongodb-driver-kotlin-extensions/index.html> + Driver Core <{+core-api+}/index.html> + +- `{+language+} Sync Driver <{+java-api+}/apidocs/mongodb-driver-kotlin-sync/index.html>`__ - + classes for the current synchronous driver API. +- `BSON kotlinx.serialization <{+java-api+}/apidocs/bson-kotlinx/index.html>`__ - + classes for encoding and decoding between Kotlin data classes and the BSON data + format using :github:`kotlinx.serialization `. +- `{+language+} Driver Extensions + <{+java-api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ - + classes that extend the core builder classes to support :ref:`data + classes `. +- `Driver Core <{+core-api+}/index.html>`__ - classes that + contain essential driver functionality. diff --git a/source/builders.txt b/source/builders.txt index 11c66f95..cbf35dad 100644 --- a/source/builders.txt +++ b/source/builders.txt @@ -10,7 +10,9 @@ Use Builders Code Pattern :depth: 2 :class: singlecol -.. .. toctree:: +.. toctree:: + + Builders & Data Classes .. /fundamentals/builders/aggregates .. /fundamentals/builders/filters @@ -53,7 +55,7 @@ The following data class models the documents in the ``users`` collection: :copyable: :dedent: -The following data class models the results returned by our query: +The following data class models the results returned by the query: .. literalinclude:: /includes/builders/builders.kt :start-after: start-result-class @@ -87,8 +89,12 @@ query filter: :copyable: :dedent: -Builders -~~~~~~~~ +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. + +Builders API +~~~~~~~~~~~~ The following example performs the query by using the builder helpers: @@ -99,6 +105,14 @@ The following example performs the query by using the builder helpers: :copyable: :dedent: +Use Builders with Data Classes +------------------------------ + +The :ref:`kotlin-sync-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. + .. TODO: Uncomment as pages get built .. Available Builders diff --git a/source/builders/builders-data-classes.txt b/source/builders/builders-data-classes.txt new file mode 100644 index 00000000..e02ed70f --- /dev/null +++ b/source/builders/builders-data-classes.txt @@ -0,0 +1,249 @@ +.. _kotlin-sync-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>`__ \ No newline at end of file diff --git a/source/data-formats.txt b/source/data-formats.txt index 1f304205..14b9b934 100644 --- a/source/data-formats.txt +++ b/source/data-formats.txt @@ -21,12 +21,12 @@ Specialized Data Formats :titlesonly: :maxdepth: 1 + Data Classes Kotlin Serialization Codecs BSON Time Series -.. TODO: /data-formats/data-class .. TODO: /data-formats/extended-json Overview @@ -46,9 +46,10 @@ You can use several types of specialized document data formats in your application. To learn how to work with these data formats, see the following sections: +- Learn how to model your documents as {+language+} data classes in the + :ref:`kotlin-sync-data-format-data-classes` guide. - Learn how to work with the BSON data format in the :ref:`kotlin-sync-bson` guide. - Learn how to store and interact with time series data in the :ref:`kotlin-sync-time-series` guide. .. TODO: Uncomment these as pages get built -.. - Learn how to store and retrieve data using {+language+} data classes in the :ref:`data-classes` guide. .. - Learn how to use the Extended JSON format in the :ref:`kotlin-sync-extended-json` guide. diff --git a/source/data-formats/data-format-data-class.txt b/source/data-formats/data-format-data-class.txt new file mode 100644 index 00000000..ef44079b --- /dev/null +++ b/source/data-formats/data-format-data-class.txt @@ -0,0 +1,225 @@ +.. _kotlin-sync-data-format-data-classes: + +================================== +Document Data Format: Data Classes +================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +Overview +-------- + +In this guide, you can learn how to store and retrieve data in the +{+driver-long+} by using **{+language+} data classes**. + +Serialize and Deserialize a Data Class +-------------------------------------- + +The driver natively supports encoding and decoding {+language+} data classes for +MongoDB read and write operations by using the **default codec registry**. The +default codec registry is a collection of classes called **codecs** that +define how to encode and decode {+language+} and Java types. + +.. _kotlin-sync-example-data-class: + +Example Data Class +~~~~~~~~~~~~~~~~~~ + +The code examples in this section reference the following sample data class, which +describes a data storage device: + +.. literalinclude:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-data-class + :end-before: end-data-class + :dedent: + +Insert a Data Class +~~~~~~~~~~~~~~~~~~~ + +You can insert a ``DataStorage`` instance as shown in the following code: + +.. literalinclude:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-insert + :end-before: end-insert + :dedent: + +Retrieve a Data Class +~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve documents as ``DataStorage`` instances and print them +as shown in the following code: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-retrieve + :end-before: end-retrieve + :dedent: + + .. output:: + :language: console + + DataStorage(productName=tape, capacity=5.0) + +.. include:: /includes/data-formats/builders-dataclass.rst + +You must specify a class for documents returned from a collection, even +if it is different than the class you specified when retrieving the +collection. + +The following example performs an update to the document +represented by the ``DataStorage`` data class in the previous example +and returns the updated document as a ``DataStorageAlt`` type. The +operation adds the ``releaseDate`` field to the document in which the +value of the ``name`` field is ``tape``: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-alt-retrieve + :end-before: end-alt-retrieve + :dedent: + + .. output:: + :language: console + + Document after update: + DataStorageAlt(productName=tape, capacity=5.0, releaseDate=2025-01-24) + +.. _kotlin-sync-data-class-annotations: + +Specify Component Conversion Using Annotations +---------------------------------------------- + +This section describes the annotations you can use to configure the +serialization behavior of data classes and provides an example to +demonstrate the annotation behavior. + +You can use the following annotations on data classes: + +.. list-table:: + :header-rows: 1 + :stub-columns: 1 + :widths: 30 70 + + * - Annotation Name + - Description + + * - ``BsonId`` + - Marks a property to serialize as the ``_id`` property. + + * - ``BsonProperty`` + - Specifies a custom document field name when converting the data class + field to BSON. + + * - ``BsonRepresentation`` + - Specifies the BSON type MongoDB uses to store the value. Use this + annotation only when you need to store a value as a different + BSON type than the data class property. + + :red:`WARNING:` Your code might throw an exception if you include the + ``BsonRepresentation`` annotation on a property that you store + as the same type as the data class property. + +To learn more these property annotations, +see to the `org.bson.codecs.pojo.annotations +<{+java-api+}/apidocs/bson/org/bson/codecs/pojo/annotations/package-summary.html>`__ +Package API documentation. + +Annotated Data Class Example +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The code examples in this section reference the following sample data +class, which describes a network device: + +.. literalinclude:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-ann-class + :end-before: end-ann-class + :dedent: + +Insert an Annotated Data Class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can insert a ``NetworkDevice`` instance as shown in the following code: + +.. literalinclude:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-insert-ann + :end-before: end-insert-ann + :dedent: + +The inserted document in MongoDB should resemble the following: + +.. code-block:: json + :copyable: false + + { + "_id": {...}, + "name": "Enterprise Wi-fi", + "type": "router" + } + +Retrieve an Annotated Data Class +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can retrieve documents as ``NetworkDevice`` instances and print them +as shown in the following code: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-retr-ann + :end-before: end-retr-ann + :dedent: + + .. output:: + :language: console + + [NetworkDevice(deviceId=..., name=Enterprise Wi-fi, deviceType=router)] + +Operations with Recursive Types +------------------------------- + +The driver natively supports encoding and decoding of recursively +defined data classes without causing runtime recursion. This support extends +to cycles of multiple data class types in type definitions. The following +code provides an example of a recursive data class design: + +.. literalinclude:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-recur-class + :end-before: end-recur-class + :dedent: + +You can perform read and write operations on recursively defined data classes the same +way you would for other data classes. The following code shows how you can +execute a find operation on a collection of ``DataClassTree`` types: + +.. io-code-block:: + :copyable: true + + .. input:: /includes/data-formats/data-class.kt + :language: kotlin + :start-after: start-tree-retrieve + :end-before: end-tree-retrieve + :dedent: + + .. output:: + :language: console + + DataClassTree(content=indo-european, + left=DataClassTree(content=germanic, left=DataClassTree(...)), + right=DataClassTree(content=romance, ...)) diff --git a/source/includes/data-formats/builders-dataclass.rst b/source/includes/data-formats/builders-dataclass.rst new file mode 100644 index 00000000..44bb1c7c --- /dev/null +++ b/source/includes/data-formats/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-sync-builders-data-classes` guide. \ No newline at end of file diff --git a/source/includes/data-formats/data-class.kt b/source/includes/data-formats/data-class.kt new file mode 100644 index 00000000..ef55c4bd --- /dev/null +++ b/source/includes/data-formats/data-class.kt @@ -0,0 +1,114 @@ +import com.mongodb.client.model.Filters +import com.mongodb.client.model.Filters.* +import com.mongodb.client.model.FindOneAndUpdateOptions +import com.mongodb.client.model.ReturnDocument +import com.mongodb.client.model.Updates +import com.mongodb.kotlin.client.MongoClient +import org.bson.BsonType +import org.bson.codecs.pojo.annotations.BsonId +import org.bson.codecs.pojo.annotations.BsonProperty +import org.bson.codecs.pojo.annotations.BsonRepresentation +import org.bson.types.ObjectId +import java.time.LocalDate + +// start-data-class +data class DataStorage(val productName: String, val capacity: Double) +// end-data-class + +// start-ann-class +data class NetworkDevice( + @BsonId + @BsonRepresentation(BsonType.OBJECT_ID) + val deviceId: String, + val name: String, + @BsonProperty("type") + val deviceType: String +) +// end-ann-class + +// start-recur-class +data class DataClassTree( + val content: String, + val left: DataClassTree?, + val right: DataClassTree? +) +// end-recur-class + + +fun main() { + val uri = "" + + val mongoClient = MongoClient.create(uri) + val database = mongoClient.getDatabase("sample_db") + + // start-insert + val collection = database.getCollection("data_storage") + val record = DataStorage("tape", 5.0) + collection.insertOne(record) + // end-insert + + // start-retrieve + val result = collection.find().firstOrNull() + println("${result}") + // end-retrieve + + // start-alt-retrieve + // Define a data class for returned documents + data class DataStorageAlt( + val productName: String, + val capacity: Double, + val releaseDate: LocalDate + ) + + val filter = Filters.eq(DataStorage::productName.name, "tape") + val update = Updates.currentDate("releaseDate") + val options = FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER) + + // Specify the class for returned documents + val newResult = collection + .withDocumentClass() + .findOneAndUpdate(filter, update, options) + + println("Document after update:\n${newResult}") + // end-alt-retrieve + + // start-insert-ann + val ntwkColl = database.getCollection("network_devices") + val deviceId = ObjectId().toHexString() + val device = NetworkDevice(deviceId, "Enterprise Wi-fi", "router") + ntwkColl.insertOne(device) + // end-insert-ann + + // start-retr-ann + val annotatedClassResult = ntwkColl.find().toList() + println(annotatedClassResult) + // end-retr-ann + + val treeColl1 = database.getCollection("language_trees") + val exampleTree = DataClassTree( + "indo-european", + DataClassTree( + "germanic", + DataClassTree("german", null, DataClassTree("high german", null, null)), + DataClassTree( + "norse", DataClassTree("swedish", null, null), + DataClassTree("danish", null, null) + ) + ), + DataClassTree( + "romance", + DataClassTree("spanish", null, null), + DataClassTree("french", null, null) + ) + ) + treeColl1.insertOne(exampleTree) + + // start-tree-retrieve + val treeColl = database.getCollection("language_trees") + + val treeFilter = Filters.eq("left.left.right.content", "high german") + val treeResult = treeColl.find(treeFilter).firstOrNull() + println(treeResult) + // end-tree-retrieve + +} \ No newline at end of file diff --git a/source/index.txt b/source/index.txt index 908c1c06..ce69ff27 100644 --- a/source/index.txt +++ b/source/index.txt @@ -23,13 +23,13 @@ Specialized Data Formats Builders Security - In-Use Encryption + In-Use Encryption Compatibility Validate Driver Signatures What's New Issues & Help View the Source - API Documentation <{+api+}/com.mongodb.kotlin.client/index.html> + API Documentation Introduction ------------ @@ -39,15 +39,11 @@ MongoDB driver for synchronous {+language+} applications. Download the driver by `Maven `__ or `Gradle `__, or set up a runnable project by following our Quick Start guide. -.. tip:: Other {+language+} Platforms for MongoDB +.. tip:: Kotlin Coroutine Driver If your {+language+} application requires asynchronous processing, use the :driver:`Coroutine Driver `, which uses coroutines for server-side applications. - - If you are developing an Android or Kotlin Multiplatform (KMP) - application, you can use the :realm:`MongoDB Atlas Device Kotlin SDK ` - to implement Device Sync and to manage your Realm data. Get Started ----------- From f875decc4dad7c268f2a6e971b8776ad607aa10f Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 24 Jan 2025 14:21:45 -0500 Subject: [PATCH 2/4] wip --- source/builders.txt | 11 ++ source/builders/builders-data-classes.txt | 81 ++++++---- .../includes/builders/builders-data-class.kt | 151 ++++++++++++++++++ source/whats-new.txt | 6 + 4 files changed, 215 insertions(+), 34 deletions(-) create mode 100644 source/includes/builders/builders-data-class.kt diff --git a/source/builders.txt b/source/builders.txt index cbf35dad..f71c55c1 100644 --- a/source/builders.txt +++ b/source/builders.txt @@ -30,6 +30,17 @@ benefits of using the provided builders. The {+driver-short+} provides type-safe builder classes and methods that enable developers to efficiently build queries and aggregations. +To learn more about the available builder classes and methods, see the +following API documentation sections: + +- `Accumulators <{+core-api+}/com/mongodb/client/model/Accumulators.html>`__ +- `Aggregates <{+core-api+}/com/mongodb/client/model/Aggregates.html>`__ +- `Filters <{+core-api+}/com/mongodb/client/model/Filters.html>`__ +- `Indexes <{+core-api+}/com/mongodb/client/model/Indexes.html>`__ +- `Projections <{+core-api+}/com/mongodb/client/model/Projections.html>`__ +- `Sorts <{+core-api+}/com/mongodb/client/model/Sorts.html>`__ +- `Updates <{+core-api+}/com/mongodb/client/model/Updates.html>`__ + Why Use Builders? ----------------- diff --git a/source/builders/builders-data-classes.txt b/source/builders/builders-data-classes.txt index e02ed70f..2e8747af 100644 --- a/source/builders/builders-data-classes.txt +++ b/source/builders/builders-data-classes.txt @@ -39,8 +39,8 @@ notation. To learn more about this notation, see `Infix notation .. 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. + examples to demonstrate this functionality. To learn more about using + builder classes, see the :ref:`kotlin-sync-builders` guide. Add {+language+} Extensions to Your Project ------------------------------------- @@ -85,7 +85,7 @@ 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. +:ref:`kotlin-sync-data-class-aggregates` example in this guide. Builders Examples ----------------- @@ -99,10 +99,8 @@ package. 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. + annotations, see the :ref:`kotlin-sync-data-class-annotations` + section of the Document Data Format: Data Classes guide. Sample Data ~~~~~~~~~~~ @@ -112,17 +110,19 @@ 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 +.. literalinclude:: /includes/builders/builders-data-class.kt + :language: kotlin + :start-after: start-data-class + :end-before: end-data-class + :dedent: -.. _kotlin-data-class-filters: +.. _kotlin-sync-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. +class properties. The following code shows different ways to use ``Filters`` extension methods to perform queries on the ``Student`` data class: @@ -132,17 +132,19 @@ methods to perform queries on the ``Student`` data class: 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 +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-filters-data-class + :end-before: end-filters-data-class + :dedent: -.. _kotlin-data-class-indexes: +.. _kotlin-sync-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. +indexes on data class properties. The following code shows different ways to use ``Indexes`` extension methods to create indexes on the ``Student`` data class: @@ -152,17 +154,19 @@ methods to create indexes on the ``Student`` data class: 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 +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-indexes-data-class + :end-before: end-indexes-data-class + :dedent: -.. _kotlin-data-class-projections: +.. _kotlin-sync-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. +projections for data class properties. The following code shows how to use ``Projections`` extension methods to create a projection on the ``Student`` data class: @@ -173,17 +177,19 @@ methods to create a projection on the ``Student`` data class: 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 +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-proj-data-class + :end-before: end-proj-data-class + :dedent: -.. _kotlin-data-class-sorts: +.. _kotlin-sync-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. +on your data class properties. The following code shows how to use ``Sorts`` extension methods to create different sorts on the ``Student`` data class: @@ -193,17 +199,19 @@ methods to create different sorts on the ``Student`` data class: import com.mongodb.client.model.Sorts.orderBy import com.mongodb.kotlin.client.model.Sorts -.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.sorts-data-class.kt +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-sorts-data-class + :end-before: end-sorts-data-class + :dedent: -.. _kotlin-data-class-updates: +.. _kotlin-sync-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. +updates by using your data class properties. The following code shows how to use ``Sorts`` extension methods to create different sorts on the ``Student`` data class: @@ -215,18 +223,20 @@ methods to create different sorts on the ``Student`` data class: 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 +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-updates-data-class + :end-before: end-updates-data-class + :dedent: -.. _kotlin-data-class-aggregates: +.. _kotlin-sync-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. +properties. The following code shows how to use ``Accumulators`` extension methods and ``Aggregates`` helper methods to perform an aggregation on @@ -239,11 +249,14 @@ the ``Student`` data class: import com.mongodb.client.model.Aggregates.sort import com.mongodb.kotlin.client.model.Accumulators.avg -.. literalinclude:: /examples/generated/BuildersDataClassTest.snippet.aggregates-data-class.kt +.. literalinclude:: /includes/builders/builders-data-class.kt :language: kotlin + :start-after: start-agg-data-class + :end-before: end-agg-data-class + :dedent: API Documentation ----------------- - `{+driver-short+} Extensions - <{+api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ \ No newline at end of file + <{+core-api+}/apidocs/mongodb-driver-kotlin-extensions/index.html>`__ diff --git a/source/includes/builders/builders-data-class.kt b/source/includes/builders/builders-data-class.kt new file mode 100644 index 00000000..b989e133 --- /dev/null +++ b/source/includes/builders/builders-data-class.kt @@ -0,0 +1,151 @@ +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.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.MongoClient +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 + +internal class BuildersDataClassTest { + + // start-data-class + data class Student( + val name: String, + val teachers: List, + val gradeAverage: Double + ) + // end-data-class + + fun main() { + val uri = "" + + val mongoClient = MongoClient.create(uri) + val database = mongoClient.getDatabase("school") + val collection = database.getCollection("students") + + // 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 + // end-filters-data-class + + collection.insertOne(student) + val filter = eq(Student::name, student.name) + val result = collection.find(filter).firstOrNull() + + // 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) + // end-indexes-data-class + + val student = Student( + "Sandra Nook", + listOf("Alvarez", "Gruber"), + 85.7 + ) + collection.insertOne(student) + + // start-proj-data-class + val combinedProj = fields( + include(Student::name, Student::gradeAverage), + excludeId() + ) + + collection.find().projection(combinedProj) + // end-proj-data-class + + data class Result(val name: String, val gradeAverage: Double) + val result = collection.find().projection(combinedProj).firstOrNull() + + 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)) + + // start-sorts-data-class + val sort = orderBy( + Sorts.descending(Student::gradeAverage), + Sorts.ascending(Student::name) + ) + + collection.find().sort(sort) + // end-sorts-data-class + + val students = listOf( + Student("Sandra Nook", listOf("Alvarez", "Gruber"),85.7), + Student("Paolo Sanchez", listOf("Gruber", "Piselli"),89.3) + ) + collection.insertMany(students) + + // 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) + // end-updates-data-class + + val result = collection.find().firstOrNull() + + 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) + + // start-agg-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) + // end-agg-data-class + + } +} \ No newline at end of file diff --git a/source/whats-new.txt b/source/whats-new.txt index f8636640..2b46786f 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -42,6 +42,12 @@ improvements, and fixes: :ref:`kotlin-sync-write-replace`, and :ref:`kotlin-sync-bulk-write` guides +- Support for using builders class methods directly with data class + properties. To learn more, see the :ref:`kotlin-sync-builders-data-classes` + guide. This functionality is supported by the `{+driver-short+} + Extensions package <{+java-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-sync-client-bulk-write` From 229d32b58857977146eca2aada26c532375440d4 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 24 Jan 2025 14:26:17 -0500 Subject: [PATCH 3/4] vale fix --- source/data-formats/data-format-data-class.txt | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/data-formats/data-format-data-class.txt b/source/data-formats/data-format-data-class.txt index ef44079b..5651f999 100644 --- a/source/data-formats/data-format-data-class.txt +++ b/source/data-formats/data-format-data-class.txt @@ -124,7 +124,7 @@ You can use the following annotations on data classes: * - ``BsonRepresentation`` - Specifies the BSON type MongoDB uses to store the value. Use this - annotation only when you need to store a value as a different + annotation only when you must store a value as a different BSON type than the data class property. :red:`WARNING:` Your code might throw an exception if you include the @@ -159,7 +159,7 @@ You can insert a ``NetworkDevice`` instance as shown in the following code: :end-before: end-insert-ann :dedent: -The inserted document in MongoDB should resemble the following: +The inserted document in MongoDB resembles the following: .. code-block:: json :copyable: false @@ -204,9 +204,10 @@ code provides an example of a recursive data class design: :end-before: end-recur-class :dedent: -You can perform read and write operations on recursively defined data classes the same -way you would for other data classes. The following code shows how you can -execute a find operation on a collection of ``DataClassTree`` types: +You can perform read and write operations on recursively defined data +classes the same way that you do for other data classes. The following +code shows how you can execute a find operation on a collection of +``DataClassTree`` types: .. io-code-block:: :copyable: true From 0ea6e7afadaca7df1ce76d3aff8e2549505607d9 Mon Sep 17 00:00:00 2001 From: rustagir Date: Fri, 24 Jan 2025 14:31:27 -0500 Subject: [PATCH 4/4] cross links --- source/builders/builders-data-classes.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/builders/builders-data-classes.txt b/source/builders/builders-data-classes.txt index 2e8747af..48af645a 100644 --- a/source/builders/builders-data-classes.txt +++ b/source/builders/builders-data-classes.txt @@ -20,9 +20,9 @@ Use Builders with Data Classes Overview -------- -In this guide, you can learn how to use your data class properties -directly with the builder classes available in -the {+driver-short+}. +In this guide, you can learn how to use your :ref:`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