Docs Menu
Docs Home
/ /

Migrar desde KMongo

Esta página contiene una comparación detallada de la mayoría de las diferencias entre el controlador oficial de MongoDB Kotlin y el controlador KMongo desarrollado por la comunidad. Puede usar esta página para identificar los cambios necesarios para migrar del controlador KMongo obsoleto al controlador oficial de MongoDB Kotlin.

KMongo es una popular biblioteca desarrollada por la comunidad para trabajar con MongoDB desde aplicaciones Kotlin. Es un contenedor del controlador de Java, creado antes de la creación del controlador oficial de Kotlin para satisfacer las necesidades de la comunidad Kotlin.

Importante

A partir del 2023 de julio, KMongo ha sido marcado como obsoleto.

El controlador MongoDB Kotlin es el controlador oficial para Kotlin, con soporte y mantenimiento. Está desarrollado por el equipo de MongoDB.

Aunque ambos controladores admiten operaciones sincrónicas y asincrónicas, los ejemplos de esta página utilizarán operaciones asincrónicas basadas en corrutinas.

El controlador Kotlin es el controlador oficial de MongoDB para Kotlin. Desarrollado por el equipo de MongoDB, proporciona una API nativa para que las aplicaciones Kotlin se conecten a MongoDB y trabajen con datos. Se implementa encapsulando el controlador Java de MongoDB.

KMongo es una popular biblioteca desarrollada por la comunidad para trabajar con MongoDB desde aplicaciones Kotlin. Es un contenedor del controlador de Java, creado antes de la creación del controlador oficial de Kotlin para satisfacer las necesidades de la comunidad Kotlin.

Importante

A partir del 2023 de julio, KMongo ha sido marcado como obsoleto.

El controlador Kotlin se desarrolló en colaboración con el creador de KMongo, Julien Buret, para ofrecer a los usuarios un controlador con soporte oficial.

El controlador oficial de Kotlin y KMongo tienen APIs generalmente similares. Entre las similitudes más notables se incluyen:

  • Soporte para operaciones síncronas y basadas en corrutinas

  • Admite el uso de clases de datos para representar documentos MongoDB

  • Compatibilidad con la serialización de KotlinX

  • Compatibilidad con la API CRUD de MongoDB y la API de agregación

Aunque el controlador oficial de Kotlin y KMongo son similares, existen algunas diferencias clave:

  • El controlador oficial no tiene soporte integrado para reactor, rxjava,2 Jackson o GSON.

  • El controlador oficial no admite comandos de shell de MongoDB.

Ambos controladores le permiten conectarse y comunicarse con clústeres MongoDB desde una aplicación Kotlin.

Para conectarse a un clúster MongoDB usando el controlador MongoDB 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>("jedi")

Vea el Conéctese a la documentación de MongoDB para obtener más información.

Para conectarse a un clúster MongoDB usando KMongo con corrutinas:

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<Jedi>()

A diferencia del controlador Kotlin de MongoDB, KMongo permite inferir el nombre de la colección a partir del nombre de la clase de datos.

Ambos controladores brindan soporte para todas las API CRUD y operaciones de agregación de MongoDB.

Tip

Si está acostumbrado a construir filtros de consulta mediante la notación infija disponible en KMongo, también puede usar esta notación para crear filtros en el controlador oficial de Kotlin mediante el uso de métodos de extensión de mongodb-driver-kotlin-extensions paquete. Seleccione el Kotlin Driver Extensions Pestaña para ver un ejemplo que utiliza esta sintaxis de consulta en el controlador Kotlin.

El controlador MongoDB Kotlin también proporciona funciones para todas las operaciones CRUD básicas:

// 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()
// 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)

Puede crear canales de agregación utilizando el método aggregate() y la función pipeline:

data class Results(val avgAge: Double)
val resultsFlow = collection.aggregate<Results>(
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) }

Consulte la documentación de Operaciones CRUD y agregación para obtener más información.

Puede usar la API de Builders de la biblioteca mongodb-driver-kotlin-extensions para crear filtros de consulta y etapas de agregación directamente mediante las propiedades de la clase de datos. Esta biblioteca también permite crear consultas mediante notación infija:

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)

Para obtener más información y ver ejemplos que utilizan todas las clases de generador, consulte la guía Usar generadores con clases de datos.

KMongo proporciona funciones para todas las operaciones CRUD básicas:

// 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")

Se pueden crear canalizaciones de agregación utilizando el método aggregate y la función pipeline:

val avgAge = collection.aggregate<Double>(
pipeline(
match(Jedi::name ne "Luke Skywalker"),
group(Jedi::name, avg(Jedi::age))
)
).toList()

Para obtener más información sobre los métodos disponibles, consulte la documentación de Descripción general de extensiones de KMongo.

Ambos controladores proporcionan soporte para consultas de tipos seguros utilizando referencias de propiedad.

Tip

Si está acostumbrado a construir filtros de consulta con la notación infija disponible en KMongo, también puede usar esta notación para crear filtros en el controlador oficial de Kotlin mediante los métodos de extensión del paquete mongodb-driver-kotlin-extensions. Seleccione la pestaña Kotlin Driver Extensions para ver un ejemplo que utiliza esta sintaxis de consulta en el controlador de Kotlin.

El controlador Kotlin de MongoDB utiliza la API Builders para crear consultas. También puede usar la clase Document.

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<Person>("people")
// Using Builders
val filter = and(eq("gender", "female"), gt("age", 29))
val projection = fields(excludeId(), include("email"))
val results = collection.find<Results>(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<Results>(filter).projection(projection)

Para asignar una consulta de cadena KMongo al controlador Kotlin, puede utilizar la clase JsonObject.

val query = JsonObject("{\"name\": \"Gabriel Garc\\u00eda M\\u00e1rquez\"}")
val jsonResult = collection.find(query).firstOrNull()

Para obtener más información, consulte la siguiente documentación del controlador Kotlin:

Puede usar la API Builders de la biblioteca mongodb-driver-kotlin-extensions para crear consultas directamente sobre las propiedades de la clase de datos. Esta biblioteca también permite crear consultas mediante notación infija:

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<Person>("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<Result>(filter).projection(projection)

Para obtener más información y ver ejemplos que utilizan todas las clases de generador, consulte la guía Usar generadores con clases de datos.

Con KMongo, puede crear consultas utilizando referencias de propiedades en la clase de datos que representa objetos en una colección y operadores infijos que proporciona la biblioteca.

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 también admite consultas de cadena que le permiten construir consultas con el lenguaje de consulta MongoDB:

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<Jedi>("""[ {$match:{age:{$lt : ${yoda.age}}}},
{$sample:{size:1}}
]""").first()

Para obtener más información, consulte la siguiente documentación de KMongo:

Ambos controladores admiten el uso de clases de datos de Kotlin y la clase Document para modelar los datos almacenados en una colección de MongoDB. La clase Document permite modelar los datos representados en una colección de MongoDB en un formato flexible.

Puede utilizar clases de datos y clases Document para modelar datos con el controlador Kotlin de MongoDB:

// With data class
data class Movie(val title: String, val year: Int, val rating: Float)
val dataClassCollection = database.getCollection<Movie>("movies")
val movieDataClass = dataClassCollection.findOneOrNull()
val movieNameDataClass = movieDataClass.title
// With Document class
val documentCollection = database.getCollection<Movie>("movies")
val movieDocument = documentCollection.findOneOrNull()
val movieTitleDocument = movieDocument.getString("title")

Puede utilizar clases de datos y clases Document para modelar datos en KMongo:

// With data class
data class Movie(val title: String, val year: Int, val rating: Float)
val collection = database.getCollection<Movie>("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")

Ambos controladores proporcionan soporte para serializar y deserializar objetos de datos en Kotlin hacia y desde BSON.

Puede serializar clases de datos en el controlador Kotlin utilizando códecs automáticos de clases de datos y la biblioteca kotlinx.serialization. El controlador proporciona un serializador Bson eficiente que gestiona la serialización de objetos Kotlin a datos BSON.

@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
)

Para obtener más información, consulta la documentación de Kotlin Serialization.

Si usa la clase Document para representar su colección, puede serializarla en JSON y EJSON usando el método .toJson():

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)

Para obtener más información sobre la serialización de datos con la Document clase, consulte la documentación Formato de datos del documento - JSON extendido.

Puede serializar datos en KMongo utilizando las siguientes bibliotecas de serialización:

  • Jackson (por defecto)

  • POJO Codec engine

  • kotlinx.serialization

// Using KotlinX Serialization
@Serializable
data class Data(@Contextual val _id: Id<Data> = newId())
val json = Json { serializersModule = IdKotlinXSerializationModule }
val data = Data()
val json = json.encodeToString(data)

Para obtener más información sobre los métodos de serialización de KMongo, consulte la documentación de Mapeo de objetos de KMongo.

Ambos controladores admiten operaciones sincrónicas y asincrónicas.

El controlador Kotlin de MongoDB también cuenta con bibliotecas independientes para operaciones síncronas y asíncronas. Sin embargo, solo admite corrutinas como paradigma asíncrono. Actualmente, no es compatible con otros paradigmas asíncronos como Reactive Streams, Reactor o RxJava2.

Controlador
Paquete

Sincronizar

com.mongodb.kotlin.client

Corrutinas

com.mongodb.kotlin.client.coroutine

A diferencia de KMongo, si desea escribir código asincrónico, solo necesita importar el paquete relevante.

Para escribir código sincrónico:

import com.mongodb.kotlin.client.MongoClient
// Instantiate your collection
data class Jedi(val name: String, val age: Int)
val uri = "<your-connection-string">
val mongoClient = MongoClient.create(uri)
val database = mongoClient.getDatabase("test")
val collection = database.getCollection<Jedi>("jedi")
// Synchronous operations
val jedi = Jedi("Luke Skywalker", 19)
collection.insertOne(jedi)

Para escribir código de corrutina asincrónica:

import com.mongodb.kotlin.client.coroutine.MongoClient
// Instantiate your collection
data class Jedi(val name: String, val age: Int)
val uri = "<your-connection-string">
val mongoClient = MongoClient.create(uri)
val database = mongoClient.getDatabase("test")
val collection = database.getCollection<Jedi>("jedi")
runBlocking {
// Async operations
val jedi = Jedi("Luke Skywalker", 19)
collection.insertOne(jedi)
}

KMongo tiene una biblioteca central org.litote.kmongo:kmongo con funcionalidad principal y bibliotecas complementarias separadas que brindan soporte asincrónico a la biblioteca central.

KMongo admite los siguientes paradigmas asincrónicos:

Estilo asíncrono
Paquete

Flujos reactivos

org.litote.kmongo:kmongo-async

Corrutinas

com.mongodb.kotlin.client.coroutine and org.litote.kmongo.coroutine

Reactor

org.litote.kmongo:kmongo-reactor

RxJava2

org.litote.kmongo:kmongo-rxjava2

Para escribir código sincrónico con KMongo:

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<Jedi>()
// Synchronous operations
col.insertOne(Jedi("Luke Skywalker", 19))
val yoda : Jedi? = col.findOne(Jedi::name eq "Yoda")

Para escribir código de corrutina asincrónica con KMongo:

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<Jedi>()
runBlocking {
// Async operations
col.insertOne(Jedi("Luke Skywalker", 19))
val yoda : Jedi? = col.findOne(Jedi::name eq "Yoda")
}

Para obtener más información, consulte la Guía de inicio rápido en la documentación de KMongo.

Ahora que conoce las diferencias entre KMongo y el controlador MongoDB Kotlin, consulte la Guía de inicio rápido para comenzar a utilizar el controlador KMongo Kotlin.

Volver

Compatibilidad

En esta página