diff --git a/source/faq.txt b/source/faq.txt
index 8ff74535..2c0cd2b7 100644
--- a/source/faq.txt
+++ b/source/faq.txt
@@ -25,11 +25,7 @@ developed by the MongoDB team and provides a native API for Kotlin
applications to connect to MongoDB and work with data. It is implemented
by wrapping the :driver:`MongoDB Java driver `.
-`KMongo `__ is a popular community-developed library
-for working with MongoDB from Kotlin applications.
-It is also a wrapper around the Java driver.
-It was created prior to the creation of the official Kotlin driver to serve
-the needs of the Kotlin community.
+.. include:: /includes/kmongo-description.rst
The Kotlin driver was developed in collaboration with the creator of KMongo,
Julien Buret, to give users an officially-supported driver.
@@ -48,11 +44,13 @@ 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 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 `.
+
.. _kotlin-faq-connection-pool:
How Does Connection Pooling Work in the Kotlin Driver?
diff --git a/source/includes/kmongo-description.rst b/source/includes/kmongo-description.rst
new file mode 100644
index 00000000..cc3ecbda
--- /dev/null
+++ b/source/includes/kmongo-description.rst
@@ -0,0 +1,5 @@
+`KMongo `__ is a popular community-developed library
+for working with MongoDB from Kotlin applications.
+It is also a wrapper around the Java driver.
+It was created prior to the creation of the official Kotlin driver to serve
+the needs of the Kotlin community. As of July 2023, it has been marked as deprecated.
\ No newline at end of file
diff --git a/source/index.txt b/source/index.txt
index 9ff9d615..cbfd973c 100644
--- a/source/index.txt
+++ b/source/index.txt
@@ -16,6 +16,7 @@ MongoDB Kotlin Driver
/connection-troubleshooting
/issues-and-help
/compatibility
+ /migrate-kmongo
View the Source
Introduction
diff --git a/source/migrate-kmongo.txt b/source/migrate-kmongo.txt
new file mode 100644
index 00000000..8b8938be
--- /dev/null
+++ b/source/migrate-kmongo.txt
@@ -0,0 +1,518 @@
+.. _kotlin-migrate-kmongo:
+
+===================
+Migrate from KMongo
+===================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 1
+ :class: singlecol
+
+
+Overview
+--------
+
+This page contains a high-level comparison of most of the ways the official
+MongoDB Kotlin 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.
+
+.. 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.
+
+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.
+
+.. tabs::
+
+ .. tab::
+ :tabid: {+driver-long+}
+
+ To connect to a MongoDB cluster using the MongoDB Kotlin driver:
+
+ .. code-block:: kotlin
+
+ import com.mongodb.kotlin.client.coroutine.MongoClient
+
+ 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
+
+ val mongoClient = MongoClient.create(uri)
+
+ val database = mongoClient.getDatabase("test")
+ // Get a collection of documents of type Jedi
+ val collection = database.getCollection("jedi")
+
+ See the :ref:`Connect to MongoDB ` documentation for more
+ information.
+
+ .. tab::
+ :tabid: KMongo
+
+ To connect to a MongoDB cluster using KMongo with coroutines:
+
+ .. code-block:: kotlin
+
+ import org.litote.kmongo.reactivestreams.*
+ import org.litote.kmongo.coroutine.*
+
+ data class Jedi(val name: String, val age: Int)
+
+ // Get new MongoClient instance using coroutine extension
+ val client = KMongo.createClient().coroutine
+
+ val database = client.getDatabase("test")
+ // Get a collection of documents of type Jedi
+ val col = database.getCollection()
+
+ Unlike the MongoDB Kotlin driver, KMongo allows the collection name to be
+ inferred from the data class name.
+
+CRUD and Aggregation
+--------------------
+
+Both drivers provide support for all MongoDB CRUD APIs and aggregation
+operations.
+
+.. tabs::
+
+ .. tab::
+ :tabid: {+driver-long+}
+
+ The MongoDB Kotlin driver also provides functions for all basic CRUD operations:
+
+ .. code-block:: kotlin
+
+ // Insert a document
+ val jedi =a 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()
+
+ // 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)
+
+ Aggregation pipelines can be built using the ``aggregate`` method and the
+ ``pipeline`` function:
+
+ .. code-block:: kotlin
+
+ 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) }
+
+ See the :ref:`CRUD Operations ` and
+ :ref:`Aggregation ` documentation for more information.
+
+ .. tab::
+ :tabid: KMongo
+
+ KMongo provides functions for all basic CRUD operations:
+
+ .. code-block:: kotlin
+
+ // Insert a document
+ val jedi = Jedi("Luke Skywalker", 19)
+ col.insertOne(jedi)
+
+ // Find a document
+ val luke = col.findOne(Jedi::name eq "Luke Skywalker")
+ val jedis = col.find(Jedi::age lt 30).toList()
+
+ // Update a document
+ col.updateOne(Jedi::name eq "Luke Skywalker", setValue(Jedi::age, 20))
+
+ // Delete a document
+ col.deleteOne(Jedi::name eq "Luke Skywalker")
+
+ Aggregation pipelines can be built using the ``aggregate`` method and the
+ ``pipeline`` function:
+
+ .. code-block:: kotlin
+
+ val avgAge = collection.aggregate(
+ pipeline(
+ match(Jedi::name ne "Luke Skywalker"),
+ group(Jedi::name, avg(Jedi::age))
+ )
+ ).toList()
+
+ For more information on available methods, see the
+ `Extensions Overview `__ KMongo
+ documentation.
+
+Construct Queries
+-----------------
+
+Both drivers provide support for type-safe queries using property references.
+
+.. tabs::
+
+ .. tab::
+ :tabid: {+driver-long+}
+
+ The MongoDB Kotlin driver 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.
+
+ .. 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:
+
+ - :ref:`Builders `
+ - :ref:`Documents ` guide
+ - `JsonObject <{+api+}/apidocs/bson/org/bson/json/JsonObject.html>`__ API Documentation
+
+ .. tab::
+ :tabid: KMongo
+
+ With KMongo, you can create queries using property references on the data class
+ that represents objects in a collection and infix operators that the library
+ provides.
+
+ .. code-block:: kotlin
+
+ data class Jedi(val name: String)
+
+ val yoda = col.findOne(Jedi::name eq "Yoda")
+
+ // Compile error (2 is not a String)
+ val error = col.findOne(Jedi::name eq 2)
+
+ // Use property reference with instances
+ val yoda2 = col.findOne(yoda::name regex "Yo.*")
+
+ KMongo also supports string queries that let you construct queries with
+ MongoDB Query Language:
+
+ .. code-block:: kotlin
+
+ import org.litote.kmongo.MongoOperator.lt
+ import org.litote.kmongo.MongoOperator.match
+ import org.litote.kmongo.MongoOperator.regex
+ import org.litote.kmongo.MongoOperator.sample
+
+ val yoda = col.findOne("{name: {$regex: 'Yo.*'}}")!!
+ val luke = col.aggregate("""[ {$match:{age:{$lt : ${yoda.age}}}},
+ {$sample:{size:1}}
+ ]""").first()
+
+ For more information, see the following KMongo documentation:
+
+ - `Typed Queries `_
+ - `Mongo Shell Queries `__
+
+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.
+
+.. tabs::
+
+ .. tab::
+ :tabid: {+driver-long+}
+
+ You can use data classes and ``Document`` classes to model data with the
+ MongoDB Kotlin driver:
+
+ .. code-block:: kotlin
+
+ // With data class
+ data class Movie(val title: String, val year: Int, val rating: Float)
+
+ val dataClassCollection = database.getCollection("movies")
+ val movieDataClass = dataClassCollection.findOneOrNull()
+ val movieNameDataClass = movieDataClass.title
+
+ // With Document class
+ val documentCollection = database.getCollection("movies")
+ val movieDocument = documentCollection.findOneOrNull()
+ val movieTitleDocument = movieDocument.getString("title")
+
+ .. tab::
+ :tabid: KMongo
+
+ You can use data classes and ``Document`` classes to model data in KMongo:
+
+ .. code-block:: kotlin
+
+ // With data class
+ data class Movie(val title: String, val year: Int, val rating: Float)
+
+ val collection = database.getCollection("movies")
+ val movieDataClass = dataClassCollection.findOne()
+ val movieNameDataClass = movieDataClass.title
+
+ // With Document class
+ val documentCollection = database.getCollection("movies")
+ val movieDocument = documentCollection.findOne()
+ val movieTitleDocument = movieDocument.getString("title")
+
+Data Serialization
+------------------
+
+Both drivers provide support for serializing and deserializing data objects
+in Kotlin 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
+ driver provides an efficient ``Bson`` serializer that handles the
+ serialization of Kotlin objects to BSON data.
+
+ .. code-block:: kotlin
+
+ @Serializable
+ data class LightSaber(
+ @SerialName("_id") // Use instead of @BsonId
+ @Contextual val id: ObjectId?,
+ val color: String,
+ val qty: Int,
+ @SerialName("brand")
+ val manufacturer: String = "Acme" // Use instead of @BsonProperty
+ )
+
+ To learn more, see the :ref:`Kotlin Serialization `
+ documentation.
+
+ If you use the ``Document`` class to represent your collection, you can
+ serialize it to JSON and EJSON using the ``.toJson()`` method:
+
+ .. code-block:: kotlin
+
+ val document = Document("_id", 1).append("color", "blue")
+
+ // Serialize to JSON
+ document.toJson()
+
+ // Serialize to EJSON
+ val settings = JsonWriterSettings.builder().outputMode(JsonMode.STRICT).build()
+ val json = doc.toJson(settings)
+
+ To learn more about serializing data with the ``Document`` class, refer to
+ :ref:`Document Data Format - Extended JSON ` documentation.
+
+ .. tab::
+ :tabid: KMongo
+
+ You can serialize data in KMongo using the following serialization libraries:
+
+ * ``Jackson`` (default)
+ * ``POJO Codec engine``
+ * ``kotlinx.serialization``
+
+ .. code-block:: kotlin
+
+ // Using KotlinX Serialization
+ @Serializable
+ data class Data(@Contextual val _id: Id = newId())
+
+ val json = Json { serializersModule = IdKotlinXSerializationModule }
+ val data = Data()
+ val json = json.encodeToString(data)
+
+ To learn more about the KMongo serialization methods, refer to the
+ `Object Mapping `__
+ KMongo documentation.
+
+.. _kotlin-sync-async-support:
+
+Synchronous and Asynchronous Support
+------------------------------------
+
+Both drivers support synchronous and asynchronous operations.
+
+.. tabs::
+
+ .. 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
+ currently provide support for other asynchronous paradigms such as Reactive
+ Streams, Reactor, or RxJava2.
+
+ .. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :widths: 10 40
+
+ * - Driver
+ - Package
+
+ * - Sync
+ - | ``com.mongodb.kotlin.client``
+
+ * - Coroutines
+ - | ``com.mongodb.kotlin.client.coroutine``
+
+ Unlike KMongo, if you want to write asynchronous code, you only need to import
+ the relevant package.
+
+ To write synchronous code:
+
+ .. code-block:: kotlin
+
+ import com.mongodb.kotlin.client.MongoClient
+
+ // Instantiate your collection
+ data class Jedi(val name: String, val age: Int)
+ val uri = "
+ val mongoClient = MongoClient.create(uri)
+ val database = mongoClient.getDatabase("test")
+ val collection = database.getCollection("jedi")
+
+ // Synchronous operations
+ val jedi =a Jedi("Luke Skywalker", 19)
+ collection.insertOne(jedi)
+
+ To write asynchronous coroutine code:
+
+ .. code-block:: kotlin
+
+ import com.mongodb.kotlin.client.coroutine.MongoClient
+
+ // Instantiate your collection
+ data class Jedi(val name: String, val age: Int)
+ val uri = "
+ val mongoClient = MongoClient.create(uri)
+ val database = mongoClient.getDatabase("test")
+ val collection = database.getCollection("jedi")
+
+ runBlocking {
+
+ // Async operations
+ val jedi =a Jedi("Luke Skywalker", 19)
+ collection.insertOne(jedi)
+ }
+
+ .. tab::
+ :tabid: KMongo
+
+ KMongo has a core library ``org.litote.kmongo:kmongo`` with main functionality and
+ separate companion libraries that provide asynchronous support to the core library.
+
+ KMongo supports the following asynchronous paradigms:
+
+ .. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :widths: 10 40
+
+ * - Async Style
+ - Package
+
+ * - Reactive Streams
+ - | ``org.litote.kmongo:kmongo-async``
+
+ * - Coroutines
+ - | ``com.mongodb.kotlin.client.coroutine`` and ``org.litote.kmongo.coroutine``
+
+ * - Reactor
+ - | ``org.litote.kmongo:kmongo-reactor``
+
+ * - RxJava2
+ - | ``org.litote.kmongo:kmongo-rxjava2``
+
+ To write synchronous code with KMongo:
+
+ .. code-block:: kotlin
+
+ import org.litote.kmongo.*
+
+ // Instantiate your collection
+ data class Jedi(val name: String, val age: Int)
+
+ val client = KMongo.createClient()
+ val database = client.getDatabase("test")
+ val col = database.getCollection()
+
+ // Synchronous operations
+ col.insertOne(Jedi("Luke Skywalker", 19))
+ val yoda : Jedi? = col.findOne(Jedi::name eq "Yoda")
+
+ To write async coroutine code with KMongo:
+
+ .. code-block:: kotlin
+
+ import org.litote.kmongo.reactivestreams.*
+ import org.litote.kmongo.coroutine.*
+
+ // Instantiate your collection
+ data class Jedi(val name: String, val age: Int)
+
+ val client = KMongo.createClient()
+ val database = client.getDatabase("test")
+ val col = database.getCollection()
+
+ runBlocking {
+
+ // Async operations
+ col.insertOne(Jedi("Luke Skywalker", 19))
+ val yoda : Jedi? = col.findOne(Jedi::name eq "Yoda")
+ }
+
+ To learn more, refer to the `Quick Start `__
+ in the KMongo documentation.
+
+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.
diff --git a/source/quick-start.txt b/source/quick-start.txt
index d7a86939..cb0b143c 100644
--- a/source/quick-start.txt
+++ b/source/quick-start.txt
@@ -1,4 +1,4 @@
-.. _kotlin-sync-quickstart:
+.. _kotlin-quickstart:
===========
Quick Start