KMongo からの移行
Overview
このページには、公式のMongoDB Kotlinドライバーとコミュニティが開発した KMongo ドライバーの違いのほとんどの高レベルの比較が含まれています。 このページを使用して、非推奨の KMongo ドライバーから公式のMongoDB Kotlinドライバーに移行するために必要な変更を識別できます。
KMongo は、 KotlinアプリケーションからMongoDBを操作するための一般的なコミュニティ開発ライブラリです。これは、公式のKotlinドライバーの作成より前に作成されたJavaドライバーを囲み、 Kotlinコミュニティのニーズに対応するためのラッパーです。
重要
2023 年 7 月現在、KMongo は非推奨としてマークされています。
MongoDB Kotlinドライバーは、公式にサポートされ、維持されているKotlin用のMongoDBドライバーです。 これは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 ではコレクション名をデータクラス名から推測することができます。
CRUD と集計
どちらのドライバーも、すべての MongoDB CRUD API と集計操作のサポートを提供します。
Tip
KMongo で利用可能な infix 表記 を使用してクエリフィルターを作成するのに慣れる場合は、 パッケージの拡張メソッドを使用して、この表記を使用して公式のKotlinドライバーにフィルターを作成することもできます。mongodb-driver-kotlin-extensions
Kotlinドライバー でこのクエリ構文を使用する例を表示するには、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) }
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 ドライバーのドキュメントを参照してください。
ドキュメントガイド
JsonObject API ドキュメント
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
シリアライザーを提供します。
data class LightSaber( // Use instead of @BsonId val id: ObjectId?, val color: String, val qty: Int, 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 data class Data( 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 ドライバーの使用を開始してください。