Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Menu Docs
Página inicial do Docs
/ / /
Kotlin Coroutine

Migrar do KMongo

Esta página contém uma comparação de alto nível da maioria das maneiras que o driver Kotlin oficial do MongoDB e o driver KMongo desenvolvido pela comunidade diferem. Você pode usar esta página para identificar as alterações que precisa fazer para migrar do driver KMongo obsoleto para o driver oficial Kotlin do MongoDB .

KMongo é uma biblioteca popular desenvolvida na comunidade para trabalhar com o MongoDB a partir de aplicativos Kotlin. É um invólucro em torno do driver Java que foi criado antes da criação do driver oficial do Kotlin para atender às necessidades da comunidade Kotlin.

Importante

A partir de julho de 2023, o KMongo foi marcado como obsoleto.

O driver Kotlin do MongoDB é o driver MongoDB oficialmente suportado e mantido para Kotlin. É desenvolvido pela equipe MongoDB.

Embora ambos os drivers ofereçam suporte a operações síncronas e assíncronas, os exemplos nesta página usarão operações assíncronas baseadas em coroutine.

Ambos os drivers permitem que você se conecte e se comunique com clusters do MongoDB a partir de um aplicativo Kotlin.

Para se conectar a um cluster MongoDB usando o driver 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")

Consulte a documentação do Conectar ao MongoDB para mais informações.

Para se conectar a um cluster MongoDB usando o KMongo com corrotinas:

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

Ao contrário do MongoDB Kotlin Driver, o KMongo permite que o nome da coleção seja inferido a partir do nome da classe de dados.

Ambos os drivers oferecem suporte para todas as API CRUD do MongoDB e operações de agregação.

Dica

Se você está familiarizado com a construção de filtros de query usando a notação infixa disponível no KMongo, também pode usar essa notação para criar filtros no driver oficial do Kotlin usando métodos de extensão do pacote mongodb-driver-kotlin-extensions. Selecione a aba Kotlin Driver Extensions para visualizar um exemplo que utiliza esta sintaxe de consulta no driver Kotlin .

O driver Kotlin do MongoDB também fornece funções para todas as operações 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)

Você pode construir agregação pipelines utilizando o método aggregate() e a função 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 a documentação de Operações e Agregação CRUD para obter mais informações.

Você pode usar a API de construtores da biblioteca mongodb-driver-kotlin-extensions para criar filtros de consulta e estágios de pipeline de agregação diretamente usando propriedades da classe de dados. Esta biblioteca também permite criar queries usando notação infixa:

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 saber mais e visualizar exemplos que usam todas as classes de construtores, consulte o guia Usar construtores com classes de dados.

O KMongo fornece funções para todas as operações 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")

Os pipelines de agregação podem ser construídos utilizando o método aggregate e a função pipeline :

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

Para obter mais informações sobre os métodos disponíveis, consulte a Visão geral de extensões Documentação do KMongo.

Ambos os drivers oferecem suporte a query seguras por tipo usando referências de propriedade.

Dica

Se você está familiarizado com a construção de filtros de query usando a notação infixa disponível no KMongo, também pode usar essa notação para criar filtros no driver oficial do Kotlin usando métodos de extensão do pacote mongodb-driver-kotlin-extensions . Selecione a guia Kotlin Driver Extensions para visualizar um exemplo que usa essa sintaxe de consulta no driver Kotlin .

O driver Kotlin do MongoDB usa a API Builders para construir consultas. Alternativamente, você pode usar a classe 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 mapear uma query de string KMongo para o driver Kotlin, você pode usar a classe JsonObject .

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

Para obter mais informações, consulte a seguinte documentação do driver Kotlin:

Você pode utilizar a API de Construtores da biblioteca do mongodb-driver-kotlin-extensions para construir consultas diretamente nas propriedades da classe de dados. Esta biblioteca também permite criar queries usando notação infixa:

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 saber mais e visualizar exemplos que usam todas as classes de construtores, consulte o guia Usar construtores com classes de dados.

Com o KMongo, você pode criar queries usando referências de propriedade na classe de dados que representam objetos em uma coleção e operadores infixos que a biblioteca fornece.

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.*")

O KMongo também oferece suporte a queries de string que permitem construir queries com a linguagem de query do 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 obter mais informações, consulte a seguinte documentação do KMongo:

Ambos os drivers suportam o uso de classes de dados Kotlin e a classe Document para modelar os dados armazenados em uma coleção MongoDB . A classe Document permite modelar dados representados em uma coleção MongoDB em um formato flexível.

Você pode usar classes de dados e classes Document para modelar dados com o MongoDB Kotlin Driver:

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

Você pode usar classes de dados e classes Document para modelar dados no 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 os drivers fornecem suporte para serializar e desserializar objetos de dados no Kotlin de e para o BSON.

Você pode serializar classes de dados no driver Kotlin usando codecs de classe de dados automáticos e a biblioteca kotlinx.serialization. O driver fornece um serializador Bson eficiente que lida com a serialização de objetos Kotlin para dados 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 saber mais, consulte a documentação de serialização do Kotlin .

Se você utilizar a classe Document para representar sua collection, você poderá serializá-la para JSON e EJSON utilizando o 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 saber mais sobre a serialização de dados com a classe Document , consulte Formato de dados do documento - documentação JSON estendida .

Você pode serializar dados no KMongo usando as seguintes bibliotecas de serialização:

  • Jackson (padrão)

  • 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 saber mais sobre os métodos de serialização do KMongo, consulte Mapeamento de objetos Documentação do KMongo.

Ambos os drivers suportam operações síncronas e assíncronas.

O driver Kotlin do MongoDB também possui bibliotecas separadas para operações síncronas e assíncronas. No entanto, o driver Kotlin só tem suporte integrado para corrotinas como um paradigma assíncrono. Atualmente, o driver Kotlin do MongoDB não oferece suporte para outros paradigmas assíncronos, como Reactive Streams, Reactor ou RxJava2.

Driver
Pacote

sincronizar

com.mongodb.kotlin.client

Coroutines

com.mongodb.kotlin.client.coroutine

Diferentemente do KMongo, se você quiser escrever código assíncrono, só precisará importar o pacote relevante.

Para escrever código síncrono:

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 escrever código corrotina assíncrono:

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

O KMongo tem uma biblioteca principal org.litote.kmongo:kmongo com funcionalidade principal e bibliotecas complementares separadas que fornecem suporte assíncrono à biblioteca principal.

O KMongo suporta os seguintes paradigmas assíncronos:

Estilo assíncrono
Pacote

reactive streams

org.litote.kmongo:kmongo-async

Coroutines

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

Reator

org.litote.kmongo:kmongo-reactor

RxJava2

org.litote.kmongo:kmongo-rxjava2

Para escrever código síncrono com 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 escrever código coroutine assíncrono com 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 saber mais, consulte o Início Rápido na documentação do KMongo.

Agora que você leu as diferenças entre o KMongo e o driver MongoDB Kotlin, consulte o Início rápido para começar a usar o driver KMongo Kotlin.

Voltar

Compatibilidade

Nesta página