Docs 菜单
Docs 主页
/ /

从 KMongo 迁移

本页面对官方MongoDB Kotlin驱动程序和社区开发的 KMongo驱动程序的大多数区别进行了高级比较。您可以使用此页面来确定从已弃用的 KMongo驱动程序迁移到官方MongoDB Kotlin驱动程序需要进行哪些更改。

KMongo 是一个流行的社区开发的库,用于在 Kotlin 应用程序中使用 MongoDB。它是在官方 Kotlin 驱动程序创建之前为满足 Kotlin Community 的需求而创建的 Java 驱动程序的包装器。

重要

自 2023 年 7 月起,KMongo 已被标记为已弃用。

MongoDB Kotlin 驱动程序是官方支持和维护的适用于 Kotlin 的 MongoDB 驱动程序。它由 MongoDB 团队开发。

尽管这两个驱动程序都支持同步和异步操作,但本页上的示例将使用基于异步协程的操作。

Kotlin 驱动程序是 Kotlin 的官方 MongoDB 驱动程序。 它由 MongoDB 团队开发,为 Kotlin 应用程序连接到 MongoDB 并处理数据提供原生 API。 它是通过包装MongoDB Java 驱动程序来实现的。

KMongo 是一个流行的社区开发的库,用于在 Kotlin 应用程序中使用 MongoDB。它是在官方 Kotlin 驱动程序创建之前为满足 Kotlin Community 的需求而创建的 Java 驱动程序的包装器。

重要

自 2023 年 7 月起,KMongo 已被标记为已弃用。

Kotlin 驱动程序是与 KMongo 创建者 Julien Buret 合作开发的,旨在为用户提供官方支持的驱动程序。

官方 Kotlin 驱动程序和 KMongo 通常具有相似的 API。 Kotlin 驱动程序和 KMongo 之间的显着相似之处包括:

  • 支持同步和基于协程的操作

  • 支持使用数据类表示 MongoDB 文档

  • 支持 KotlinX 序列化

  • 支持MongoDB 增删改查 API和聚合API

虽然官方 Kotlin 驱动程序和 KMongo 很相似,但存在一些关键区别:

  • 官方驱动程序没有内置对 reactorrxjava2JacksonGSON 的支持。

  • 官方驱动程序支持 MongoDB Shell 命令。

这两个驱动程序都允许您从 Kotlin 应用程序连接到 MongoDB 集群并与之通信。

要使用MongoDB Kotlin驱动程序连接到MongoDB 集群:

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

有关更多信息,请参阅连接到MongoDB文档。

要使用带有协程的 KMongo 连接到MongoDB 集群,请执行以下操作:

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

与MongoDB Kotlin驱动程序不同,KMongo 允许从数据类名称推断集合名称。

这两个驱动程序都支持所有 MongoDB CRUD API 和聚合操作。

提示

如果您习惯使用 KMongo 中提供的中缀表示法构造查询筛选条件,则还可以使用此表示法通过 mongodb-driver-kotlin-extensions包中的扩展方法在官方Kotlin驱动程序中创建过滤器。选择 Kotlin Driver Extensions标签页,查看在Kotlin驱动程序中使用此查询语法的示例。

MongoDB Kotlin驱动程序还为所有基本增删改查操作提供了函数:

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

您可以使用 aggregate() 方法和 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) }

有关更多信息,请参阅CRUD聚合文档。

您可以使用 mongodb-driver-kotlin-extensions 库中的 Builders API ,通过数据类属性直接创建查询筛选器和聚合管道阶段。 该库还允许您使用中缀表示法创建查询:

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)

要学习;了解详情并查看使用所有构建器类的示例,请参阅 将构建器与数据类结合使用指南。

KMongo 为所有基本CRUD操作提供了函数:

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

可以使用aggregate方法和pipeline函数构建聚合管道:

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

有关可用方法的更多信息,请参阅 KMongo 文档扩展概述。

这两个驱动程序都支持使用属性引用的类型安全查询。

提示

如果您习惯使用 KMongo 中提供的中缀表示法构造查询筛选条件,则还可以使用此表示法通过 mongodb-driver-kotlin-extensions包中的扩展方法在官方Kotlin驱动程序中创建过滤器。选择 Kotlin Driver Extensions标签页,查看在Kotlin驱动程序中使用此查询语法的示例。

MongoDB Kotlin驱动程序使用 Builders API来构造查询。 或者,您可以使用 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)

要将 KMongo 字符串查询映射到 Kotlin 驱动程序,您可以使用JsonObject类。

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

有关更多信息,请参阅以下 Kotlin 驱动程序文档:

您可以使用 mongodb-driver-kotlin-extensions 库中的 Builders API直接构建对数据类属性的查询。 该库还允许您使用中缀表示法创建查询:

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)

要学习;了解详情并查看使用所有构建器类的示例,请参阅 将构建器与数据类结合使用指南。

借助 KMongo,您可以使用对表示集合中对象的数据类的属性引用以及库提供的中缀运算符来创建查询。

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 还支持string查询,可让您使用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()

有关更多信息,请参阅以下 KMongo 文档:

这两个驱动程序都支持使用Kotlin数据类和 Document 类对存储在MongoDB集合中的数据进行建模。 Document 类允许您以灵活的格式对MongoDB集合中表示的数据进行建模。

您可以使用数据类和 Document 类,通过MongoDB Kotlin驱动程序对数据进行建模:

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

您可以使用数据类和Document类在 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")

这两个驱动程序都支持在 Kotlin 中将数据对象与 BSON 进行序列化和反序列化。

您可以使用自动数据类编解码器和 kotlinx.serialization 库在Kotlin驱动程序中序列化数据类。该驱动程序提供了一个高效的 Bson 序列化器,用于处理Kotlin对象到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
)

要了解更多信息,请参阅Kotlin 序列化文档。

如果使用Document类表示collection,则可以使用.toJson()方法将其序列化为 JSON 和 EJSON:

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)

要了解有关使用Document类序列化数据的更多信息,请参阅文档数据格式 - 扩展 JSON文档。

您可以使用以下序列化库在 KMongo 中序列化数据:

  • Jackson (默认)

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

要学习;了解有关 KMongo 序列化方法的更多信息,请参阅对象映射 KMongo 文档。

这两个驱动程序都支持同步和异步操作。

MongoDB Kotlin驱动程序还具有用于同步和异步操作的单独库。但是,Kotlin驱动程序仅内置支持将协程作为异步范例。MongoDB Kotlin驱动程序目前不支持其他异步范例,例如响应式流、Reactor 或 RxJava2。

驱动
安装包

同步

com.mongodb.kotlin.client

协程

com.mongodb.kotlin.client.coroutine

与 KMongo 不同,如果要编写异步代码,只需导入相关包即可。

要编写同步代码:

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)

要编写异步协程代码,请执行以下操作:

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 有一个具有主要功能的核心库org.litote.kmongo:kmongo和为核心库提供异步支持的独立伴随库。

KMongo 支持以下异步范例:

异步样式
安装包

反应流

org.litote.kmongo:kmongo-async

协程

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

Reactor

org.litote.kmongo:kmongo-reactor

RxJava2

org.litote.kmongo:kmongo-rxjava2

要使用 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")

要使用 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")
}

要学习;了解更多信息,请参阅 KMongo 文档中的快速入门

现在您已经了解了 KMongo 和 MongoDB Kotlin 驱动程序之间的区别,请参阅快速入门以开始使用 KMongo Kotlin 驱动程序。

后退

兼容性

在此页面上