Overview
このガイドでは、MongoDB Scala ドライバーを使用してインデックスを作成および管理する方法を学習できます。
インデックスは、MongoDB でクエリを効率的に実行するのに役立ちます。インデックスがない場合、MongoDB はコレクションスキャンを実行し、コレクション内のすべてのドキュメントを読み取ってクエリの一致を検索する必要があります。コレクションスキャンにより、アプリケーションのパフォーマンスが低下する可能性があります。クエリに適切なインデックスが存在する場合、MongoDB はそのインデックスを使用して検査するドキュメント数を制限します。
インデックスにより、次の機能も利用できます。
効率的なソート
地理空間検索
Tip
MongoDB は、アップデート操作や削除操作のドキュメントを検索するときにもインデックスを使用します。集計パイプラインの特定のステージでは、パフォーマンスを向上させるためにインデックスも使用します。
クエリ範囲とパフォーマンス
MongoDB に対してクエリを実行する場合、コマンドには次の要素を含めることができます。
検索するフィールドと値を指定するクエリ条件
読み取り保証など、クエリの実行に影響するオプション
MongoDB が返すフィールドを指定するためのプロジェクション基準(任意)
ドキュメントが返される順序を指定するそート基準(任意)
クエリ、プロジェクション、ソートで指定されたすべてのフィールドが同じインデックスにある場合、MongoDB はインデックスから直接結果を返します。このプロセスは、カバード クエリと呼ばれます。
重要
並び替え順
ソート条件は、インデックスの順序と一致するか、その順序を逆にする必要があります。
昇順(AZ)のフィールドname age降順(9-0)のフィールド のインデックスを検討します。
name_1_age_-1
MongoDB は、データを次のいずれかでソートするときにこのインデックスを使用します。
name昇順、age降順name降順、ageの昇順
name と age の両方を昇順または両方を降順に指定するには、メモリ内でソートする必要があります。
インデックスカバレッジの詳細については、 MongoDB Serverマニュアルの 「クエリの最適化」 を参照してください。
操作上の考慮事項
次のガイドラインでは、アプリケーションでインデックスを使用する方法を最適化する方法について説明します。
クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスを構築します。
追加する各インデックスは、アクティブにディスク領域とメモリを消費するため、キャパシティー プランニングのためにインデックス メモリとディスク使用量を追跡します。
使用頻度の低いインデックスは、追加しないようにしてください。 書込み操作によってインデックス付きフィールドが更新されると、MongoDB は関連するインデックスを更新することに注意してください。
MongoDB は動的スキーマをサポートしているため、アプリケーションは名前が事前に確認できないフィールドや任意のフィールドに対してクエリを実行できます。 MongoDB 4.2では、これらのクエリをサポートするためにワイルドカード インデックスが導入されています。 ワイルドカード インデックスは、ワークロードベースのインデックス プランニングを置き換えるように設計されていません。
データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、MongoDB サーバーのドキュメントの「インデックス作成戦略」と「データ モデリングとインデックス 」を参照してください。
サンプル アプリケーション
次のサンプルアプリケーションを使用して、このページのコードをテストできます。 サンプルアプリケーション を使用するには、次の手順を実行します。
プロジェクトにScalaドライバーがインストールされていることを確認してください。詳しくは、「 ダウンロードとインストール 」のガイドを参照してください。
次のコードをコピーし、新しい
.scalaファイルに貼り付けます。このページからコード例をコピーし、 ファイル内の指定された行に貼り付けます。
import org.mongodb.scala._ import org.mongodb.scala.model.SearchIndexModel import java.util.concurrent.TimeUnit import scala.concurrent.Await import scala.concurrent.duration.Duration import org.mongodb.scala.model.Indexes object SearchIndexes { def main(args: Array[String]): Unit = { // Create a new client and connect to the server val mongoClient = MongoClient("<connection string URI>") val database = mongoClient.getDatabase("<database name>") val collection = database.getCollection("<collection name>") // Start example code here // End example code here Thread.sleep(1000) mongoClient.close() } }
サンプル データ
このガイドの例では、Atlas サンプルデータセットの sample_mflix データベースの movies コレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、Atlas を使い始める を参照してください。
インデックス タイプ
MongoDB は、データのクエリをサポートするためにさまざまなインデックス タイプをサポートしています。 以下のセクションでは、最も一般的なインデックス型について説明し、各インデックス型を作成するためのサンプルコードを示します。 インデックス タイプの完全なリストについては、サーバー マニュアルの「インデックス」を参照してください。
単一フィールド インデックス
単一フィールド インデックスは、コレクションのドキュメント内の単一のフィールドを参照するインデックスです。 単一フィールド クエリとソートのパフォーマンスが向上し、一定時間の経過後または特定のクロック時間にコレクションからドキュメントを自動的に排除するTTL インデックスをサポートします。
注意
_id_インデックスは、単一フィールド インデックスの例です。 このインデックスは、新しいコレクションが作成されるときに、 _idフィールドに自動的に作成されます。
次の例では、指定されたフィールドに昇順のインデックスを作成しています。
val index = Indexes.ascending("<field name>") val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
このセクションの以下の例を実行するには、ファイルに次のインポート ステートメントを含める必要があります。
import org.mongodb.scala._ import org.mongodb.scala.model.Indexes import org.mongodb.scala.model.IndexOptions._ import org.mongodb.scala.model.Filters._ import scala.concurrent.Await import scala.concurrent.duration._ import scala.util.{Failure, Success} import java.util.concurrent.TimeUnit
単一フィールドインデックスを作成するには、 createIndex()メソッドを使用します。 次の例では、 titleフィールドに昇順のインデックスを作成しています。
val index = Indexes.ascending("title") val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
インデックスが によって作成されたことを確認するには、listIndexes() メソッドを使用します。 次の出力に示すように、リストに title のインデックスが表示されます。
collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"title": 1}, "name": "title_1"}
以下は、titleフィールドに作成されたインデックスによってカバーされるクエリの例です。
val filter = equal("title", "Sweethearts") collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
複合インデックス
複合インデックスは、コレクションのドキュメント内の複数のフィールドへの参照を保持し、クエリとソートのパフォーマンスを向上させます。
Tip
インデックス プレフィックスについて詳しくは、MongoDB Server マニュアルのインデックス プレフィックスエントリを参照してください。
次の例では、指定された 2 つのフィールドに複合インデックスを作成しています。
val index = Indexes.compoundIndex( Indexes.descending("<field name 1>"), Indexes.ascending("<field name 2>") ) val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
このセクションの以下の例を実行するには、ファイルに次のインポート ステートメントを含める必要があります。
import org.mongodb.scala._ import org.mongodb.scala.model.Indexes import org.mongodb.scala.model.IndexOptions._ import org.mongodb.scala.model.Filters._ import scala.concurrent.Await import scala.concurrent.duration._ import scala.util.{Failure, Success} import java.util.concurrent.TimeUnit
複合インデックスを作成するには、createIndex() メソッドを使用します。 次の例では、 runtimeフィールドでは降順でインデックスを作成し、yearフィールドでは昇順でインデックスを作成します。
val index = Indexes.compoundIndex(Indexes.descending("runtime"), Indexes.ascending("year")) val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
インデックスが によって作成されたことを確認するには、listIndexes() メソッドを使用します。 次の出力に示すように、リストに runtime と year のインデックスが表示されます。
collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"runtime": -1, "year": 1}, "name": "runtime_-1_year_1"}
以下は、runtime フィールドと year フィールドに作成されたインデックスによってカバーされるクエリの例です。
val filter = and(gt("runtime", 80), gt("year", 1999)) collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
Multikey Indexes
マルチキー インデックス は、配列値のあるフィールドに対するクエリのパフォーマンスを向上させるインデックスです。createIndex() メソッドと 単一フィールドインデックスの作成に使用する構文を使用して、コレクションにマルチキーインデックスを作成できます。
マルチキーインデックスを作成するときは、次の詳細を指定する必要があります。
インデックスを作成するフィールド
各フィールドの並べ替え順序(昇順または降順)
次の例では、指定された配列値フィールドにマルチキー インデックスを作成します。
val index = Indexes.ascending("<field name>") val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
このセクションの以下の例を実行するには、ファイルに次のインポート ステートメントを含める必要があります。
import org.mongodb.scala._ import org.mongodb.scala.model.Indexes import org.mongodb.scala.model.IndexOptions._ import org.mongodb.scala.model.Filters._ import scala.concurrent.Await import scala.concurrent.duration._ import scala.util.{Failure, Success} import java.util.concurrent.TimeUnit
マルチキーインデックスを作成するには、createIndex() メソッドを使用します。 次の例では、 castフィールドに昇順のインデックスを作成しています。
val index = Indexes.ascending("cast") val observable = collection.createIndex(index) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
インデックスが作成されたことを確認するには、listIndexes() メソッドを呼び出します。 次の出力に示すように、リストに cast のインデックスが表示されます。
collection.listIndexes().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
{"v": 2, "key": {"cast": 1}, "name": "cast_1"}
以下は、castフィールドに作成されたインデックスによってカバーされるクエリの例です。
val filter = and(equal("cast", "Aamir Khan"), equal("cast", "Kajol")) collection.find(filter).first().subscribe((doc: Document) => println(doc.toJson()), (e: Throwable) => println(s"There was an error: $e"))
MongoDB 検索する と MongoDB ベクトル検索インデックス
MongoDB Search を使用すると、MongoDB Atlas でホストされているコレクションを全文検索できます。MongoDB Search インデックスは、検索の動作とインデックスを作成するフィールドを指定します。
MongoDB Vector Search を使用すると、MongoDB に保存されているベクトル埋め込みに対してセマンティック検索を実行できます。MongoDB Vector Search の詳細については、MongoDB Vector Search の概要をご覧ください。
コレクションに対して次のメソッドを呼び出して、 MongoDB Search およびMongoDB ベクトル検索インデックスを管理できます。
createSearchIndex()createSearchIndexes()listSearchIndexes()updateSearchIndex()dropSearchIndex()
注意
前述のインデックスマネジメントメソッドは非同期で実行するため、正常に実行されたことを確認する前に戻る可能性があります。インデックスの現在のステータスを確認するには、listSearchIndexes() メソッドを呼び出します。
検索インデックスおよびベクトル検索インデックスの作成
createSearchIndex() メソッドと createSearchIndexes() メソッドを使用して、1 つ以上の MongoDB Search または MongoDB ベクトル検索インデックスを作成できます。createSearchIndexes() メソッドはインデックス定義のリストを受け入れ、1 回の呼び出しで複数のインデックスを作成し、各インデックスのインデックスタイプを指定できます。
次のコード例は、MongoDB検索インデックスの作成方法を示しています。
val index = Document("mappings" -> Document("dynamic" -> true)) collection.createSearchIndex("<index name>", index) .subscribe((result: String) => ())
createSearchIndexes() メソッドを使用して複数の MongoDB Search または MongoDB ベクトル検索インデックスを作成します。
次のコード例は、1 回の呼び出しで MongoDB Search インデックスと MongoDB Vector Search インデックスを作成する方法を示しています。
val searchIdxMdl = SearchIndexModel( Option("searchIdx"), Document("analyzer" -> "lucene.standard", "mappings" -> Document("dynamic" -> true)), Option(SearchIndexType.search()) ) val vectorSearchIdxMdl = SearchIndexModel( Option("vsIdx"), Document( "fields" -> List( Document("type" -> "vector", "path" -> "embeddings", "numDimensions" -> 1536, "similarity" -> "dotProduct") ) ), Option(SearchIndexType.vectorSearch()) ) collection.createSearchIndexes(List(searchIdxMdl, vectorSearchIdxMdl)) .subscribe((result: String) => ())
MongoDB Search インデックスの定義に使用される構文の詳細については、Atlas マニュアルの「インデックス参照」ガイドを参照してください。
検索インデックスをリストする
コレクション内のすべてのMongoDB 検索インデックスを返すには、listSearchIndexes() メソッドを使用します。
次のコード例は、listSearchIndexes() メソッドが返す Observable をサブスクライブして、コレクション内の検索インデックスのリストを出力する方法を示しています。
collection.listSearchIndexes() .subscribe((result: Document) => println(result.toJson()))
検索インデックスをアップデートする
MongoDB 検索インデックスを更新するには、updateSearchIndex() メソッドを使用します。
次のコードは、検索インデックスを更新する方法を示しています。
val updateIndex = Document("mappings" -> Document("dynamic" -> false)) collection.updateSearchIndex("<index to update>", updateIndex) .subscribe((result: Unit) => ())
検索インデックスを削除する
MongoDB 検索インデックスを削除するには、dropSearchIndex() メソッドを使用します。
警告
検索インデックスとクラスターの削除は元に戻せません
検索インデックスと関連するクラスターの削除は恒久的なアクションです。MongoDB は削除された検索インデックスやデータのリカバリをサポートしません。続行する前に、バックアップの作成などの適切な措置を講じて、データ損失を避けるようにしてください。
MongoDB は、削除された検索インデックスまたはデータを復元するリクエストはサポートしていません。データの整合性と設定の管理はユーザーが行います。
次のコードは、コレクションから検索インデックスを削除する方法を示しています。
collection.dropSearchIndex("<index name>") .subscribe((result: Unit) => ())
地理空間インデックス
次の例では、GeoJSON オブジェクトを含む指定されたフィールドに2 dsphere インデックスを作成します。
val observable = collection.createIndex(Indexes.geo2dsphere("<2d index>")) Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
2dsphere インデックスの詳細については、 MongoDB Serverマニュアルの2 dsphere インデックスガイドを参照してください。
GeoJSON タイプの詳細については、 MongoDB Serverマニュアルの 「GeoJSON オブジェクト」ガイドを参照してください。
インデックスを削除する
_idフィールドのデフォルトの一意なインデックスを除く未使用のインデックスを削除できます。
次の例では、指定された名前のインデックスを 1 つ削除します。
val observable = collection.dropIndex("<index name>") Await.result(observable.toFuture(), Duration(10, TimeUnit.SECONDS))
API ドキュメント
このガイドで使用されているメソッドまたはオブジェクトの詳細については、次のAPIドキュメントを参照してください。