Docs Menu

KMongo からの移行

このページには、公式のMongoDB Kotlinドライバーとコミュニティが開発した KMongo ドライバーの違いのほとんどの高レベルの比較が含まれています。 このページを使用して、非推奨の KMongo ドライバーから公式のMongoDB Kotlinドライバーに移行するために必要な変更を識別できます。

KMongo は、 KotlinアプリケーションからMongoDBを操作するための一般的なコミュニティ開発ライブラリです。これは、公式のKotlinドライバーの作成より前に作成されたJavaドライバーを囲み、 Kotlinコミュニティのニーズに対応するためのラッパーです。

重要

2023 年 7 月現在、KMongo は非推奨としてマークされています。

MongoDB Kotlinドライバーは、公式にサポートされ、維持されているKotlin用のMongoDBドライバーです。 これはMongoDBチームによって開発されています。

どちらのドライバーも同期操作と非同期操作 をサポートしていますが、このページの例では非同期コルーチン ベースの操作を使用します。

どちらのドライバーも 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 と集計操作のサポートを提供します。

Tip

KMongo で利用可能な infix 表記 を使用してクエリフィルターを作成するのに慣れる場合は、 パッケージの拡張メソッドを使用して、この表記を使用して公式のKotlinドライバーにフィルターを作成することもできます。mongodb-driver-kotlin-extensionsKotlinドライバー でこのクエリ構文を使用する例を表示するには、Kotlin Driver Extensionsタブを選択します。

MongoDB Kotlinドライバーは、すべての基本的なCRUD操作の関数も提供します。

// 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 のドキュメント。

どちらのドライバーも、プロパティ参照を使用した型セーフなクエリのサポートを提供します。

Tip

KMongo で利用可能な infix 表記 を使用してクエリフィルターを作成するのに詳しい場合は、 mongodb-driver-kotlin-extensionsパッケージの拡張メソッドを使用して、この表記を使用して公式のKotlinドライバーにフィルターを作成することもできます。 Kotlinドライバー でこのクエリ構文を使用する例を表示するには、Kotlin Driver Extensionsタブを選択します。

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 string クエリを 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 は、MongoDB クエリ言語でクエリを構築できる string クエリもサポートしています。

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 ドキュメントを参照してください。

どちらのドライバーも、 MongoDBコレクションに保存されているデータをモデル化するために、 Kotlinデータ クラス と Documentクラスの使用をサポートしています。 Documentクラスを使用すると、 MongoDBコレクションに 柔軟な形式で表されるデータをモデル化できます。

MongoDB Kotlinドライバー では、データ クラスと Document クラスを使用してデータをモデル化できます。

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

KMongo のデータをモデル化するには、データ クラスとDocumentクラスを使用します。

// 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との間で直列化および逆直列化するためのサポートを提供します。

Kotlinドライバーでは、自動データクラスコーデックと kotlinx.serialization ライブラリの両方を使用して、データ クラスをシリアル化できます。 このドライバーは、 KotlinオブジェクトのBSONデータへの直列化を処理する効率的な 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クラスを使用してコレクションを表す場合は、 .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ドライバーは現在、Reactive Streams、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 は次の非同期パラダイムをサポートしています。

非同期スタイル
パッケージ

Reactive Streams

org.litote.kmongo:kmongo-async

コルーチン

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

リクター

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 ドライバーの使用を開始してください。