Indexes
項目一覧
インデックスは、MongoDB でクエリを効率的に実行するのに役立ちます。インデックスがない場合、MongoDB でクエリ結果を返すには、コレクション内のすべてのドキュメントをスキャンする必要があります。クエリに適切なインデックスがある場合、MongoDB ではそのインデックスを使用してスキャンが必要なドキュメント数が制限されます。
インデックスを使用するとクエリのパフォーマンスは向上しますが、インデックスを追加すると書き込み操作の動作に悪影響が生じます。書き込みと読み取りの比率が高いコレクションでは、挿入のたびにすべてのインデックスを更新する必要があるため、インデックスの使用コストは高くなります。
ユースケース
アプリケーションで同じフィールドに対して繰り返しクエリが実行される場合、それらのフィールドにインデックスを作成してパフォーマンスを向上できます。たとえば、次のシナリオについて考えてみましょう。
Scenario | インデックス タイプ |
---|---|
人事部門では従業員 ID で従業員を検索する必要がよく生じます。従業員 ID フィールドにインデックスを作成すると、クエリのパフォーマンスが向上します。 | |
営業担当者は、クライアントの情報をロケーションごとに検索する必要が頻繁にあります。ロケーションは、 埋め込みドキュメントにインデックスを作成すると、その埋め込みドキュメント全体を指定するクエリのみがインデックスを使用できます。ドキュメント内の特定のフィールドに対するクエリでは、インデックスは使用されません。 | 埋め込みドキュメントの単一フィールド インデックス |
食料品店のマネージャーは、在庫が少ない商品を確認するために、商品の名前と数量で在庫アイテムを検索することがよくあります。 item フィールドと quantity フィールドの両方に単一のインデックスを作成して、クエリのパフォーマンスを向上することができます。 |
はじめる
MongoDB Atlasでは、ドライバー メソッドまたは MongoDB Shell を使用してインデックスを作成および管理できます。 MongoDB Atlas は、MongoDB をクラウドに配置するためのフルマネージド サービスです。
MongoDB Atlas でインデックスの作成と管理
MongoDB Atlas でホストされる配置用のインデックスは、MongoDB Atlas UI または Atlas CLI で作成、管理できます。また、MongoDB Atlas には、遅いクエリを改善するインデックスの推奨、推奨されるインデックスの影響度別ランク付け、削除するインデックスの推奨機能を持つ Performance Advisor も付属します。
インデックスを MongoDB Atlas UI または Atlas CLI で作成および管理する方法については、「 インデックスの作成、表示、削除、非表示 」を参照してください。
MongoDB Atlas Performance Advisor の詳細については、「低速クエリの監視と改善 」を参照してください。
ドライバー メソッドまたは MongoDB Shell によるインデックスの作成と管理
インデックスは、ドライバー メソッドまたは MongoDB Shell で作成、管理できます。 詳細については、このページのリソースを参照してください。
詳細
インデックスは、コレクションのデータセットのごく一部を簡単に走査できる形式で保存する特別なデータ構造です。 MongoDB インデックスは B 木 を 使用します データ構造。
インデックスには、特定のフィールドまたはフィールド セットの値が、フィールド値の順に保存されます。 インデックス エントリの順序付けは、効率的な等価一致と範囲ベースのクエリ操作をサポートします。 さらに、MongoDB ではインデックスで 順序を使用してソートされた結果を返すことができます。
次の図は、インデックスを使用して一致するドキュメントを選択し、並べ替えるクエリを示します。
基本的に、MongoDB のインデックスは他のデータベース システムのインデックスと同様です。 MongoDB はコレクションレベルでインデックスを定義し、MongoDB コレクション内のドキュメントの任意のフィールドまたはサブフィールドのインデックスをサポートします。
Default _id
Index
MongoDB では、コレクションの作成中に一意のインデックスが_idフィールドに作成されます。 _id
インデックスを使用すると、クライアントが_id
フィールドに同じ値を持つ 2 つのドキュメントを挿入するのを防止できます。 _id
フィールドではこのインデックスを削除できません。
注意
シャーディングされたクラスター で、 フィールドを シャードキー として 使用し_id
ない 場合は、エラーを防ぐために、アプリケーションで フィールドの値を一意のものにする 必要_id
があります。これはほとんどの場合、標準の自動生成されたObjectId を使用して行われます。
インデックスの作成
➤ 右上の言語の選択のドロップダウンメニューを使用して、このページの例の言語を設定します。
mongo shellでインデックスを作成するには、 db.collection.createIndex()
を使用します。
db.collection.createIndex( <key and index type specification>, <options> )
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
db.collection.createIndex( { name: -1 } )
db.collection.createIndex()
メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
重要
MongoDB Compass でコレクションにインデックスを作成するには、コレクションにドキュメントが含まれている必要があります。
MongoDB Compassでインデックスを作成するには
任意。 インデックス オプションを指定します。
Compass は次のインデックス オプションをサポートしています。
オプション | 説明 | 詳細情報 | |
---|---|---|---|
バックグラウンドでのインデックスの構築 | [] をオンにすると、インデックス構築操作中に MongoDB 配置が引き続き利用可能であることを確認できます。 | ||
ユニークインデックスの作成 | [] をオンにすると、インデックス フィールドに重複する値が保存されていないようになります。 | ||
TTL を作成 | [] をオンにすると、インデックス化されたフィールド値から指定された秒数が経過すると、ドキュメントが自動的に削除されます。 | ||
部分フィルター式 | [] をオンにすると、指定されたフィルター式に一致するドキュメントのみがインデックス化されます。 たとえば、次の部分フィルタ式は、
| ||
カスタム照合の使用 | [] をオンにすると、Compass に提供されるオプションを使用してインデックスのカスタム照合が作成されます。 | ||
ワイルドカード プロジェクション | オンにすると、インデックス内の指定されたプロジェクションと一致する未知のフィールドまたは任意のフィールドがサポートされます。 |
.NET ドライバーを使用してインデックスを作成するには、MongoCollection.CreateIndex を使用します。
collection.CreateIndex( IndexKeys<collection>.<key and index type specification>, <options> );
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.CreateIndex( IndexKeys<collection>.Descending("name") );
MongoCollection.CreateIndexメソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
非同期 Java ドライバーを使用してインデックスを作成するには、com.mongodb.async.client.MongoCollection.createIndex を使用します。
collection.createIndex( <key and index type specification>, <options>, <callbackFunction>)
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.createIndex(Indexes.descending("name"), someCallbackFunction());
com.mongodb.async.client.MongoCollection.createIndex メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Java ドライバーを使用してインデックスを作成するには、com.mongodb.client.MongoCollection.createIndex を使用します。
collection.createIndex( <key and index type specification>, <options> )
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.createIndex(Indexes.descending("name"));
com.mongodb.client.MongoCollection.createIndex 。メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Motor ドライバーを使用してインデックスを作成するには、motor.motor_asyncio.AsyncIOMotorCollection.create_index
を使用します。
await db.collection.create_index([(<key and index type specification>)], <options> )
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
await collection.create_index([("name", pymongo.DESCENDING)])
Themotor.motor_asyncio.AsyncIOMotorCollection.create_index
メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Node.JS ドライバーを使用してインデックスを作成するには、 createIndex()
を使用します。
collection.createIndex( { <key and index type specification> }, function(err, result) { console.log(result); callback(result); }
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.createIndex( { name : -1 }, function(err, result) { console.log(result); callback(result); }
createIndex()
メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Perl ドライバー を使用してインデックスを作成するには、create_one() を使用します。
my $indexes = $db->get_collection( <collection> )->indexes; $indexes->create_one( [ <key and index type specification> ] );
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
my $indexes = $db->get_collection( <collection> )->indexes; $indexes->create_one( [ name => -1 ] );
create_one() メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
PHP ドライバーを使用してインデックスを作成するには、MongoDB\\Collection::createIndex()
を使用します。
$collection->createIndex(<key and index type specification>, <options>);
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
$collection->createIndex(['name' => -1]);
MongoDB\\Collection::createIndex()
メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
PyMongo Python ドライバー を使用してインデックスを作成するには に適用されている場合には、pymongo.collection.Collection.create_index
を使用します。
db.collection.create_index([(<key and index type specification>)], <options> )
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.create_index([("name", pymongo.DESCENDING)])
Thepymongo.collection.Collection.create_index
メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Ruby ドライバー を使用してインデックスを作成するには、Mongo::Index::View#create_one を使用します。
client[:collection].indexes.create_one({ <key and index type specification> }, {options})
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
client[:collection].indexes.create_one({ name: -1 })
Mongo::Index::View#create_one メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
Scala ドライバーを使用してインデックスを作成するには、org.mongodb.scala.model.Indexes を使用します。
collection.createIndex(<key and index type specification>)
次の例では、 name
フィールドに単一キーの降順インデックスを作成しています。
collection.createIndex(descending("name"))
org.mongodb.scala.model.Indexes メソッドは、同じ仕様のインデックスがまだ存在しない場合にのみインデックスを作成します。
[1] | MongoDB インデックスは B 木データ構造を使用します。 |
インデックス名
インデックスのデフォルト名はインデックスされたキーと、インデックス内の各キーの方向(1 または -1)をアンダースコアを区切り文字に使用して連結したものです。 たとえば、 { item : 1, quantity: -1 }
に作成されたインデックスにはitem_1_quantity_-1
という名前が付けられます。
デフォルトよりも人間が判読可能なインデックスを作成できます。 たとえば、 products
コレクションを頻繁にクエリして既存の在庫にデータを入力するアプリケーションを考えてみましょう。 次のcreateIndex()
メソッドは、 item
とquantity
にquery for
inventory
という名前のインデックスを作成します。
db.products.createIndex( { item: 1, quantity: -1 } , { name: "query for inventory" } )
db.collection.getIndexes()
メソッドを使用してインデックス名を表示できます。 一度作成したインデックス名は変更できません。 代わりに、インデックスを 削除 して新しい名前で再作成する必要があります。
インデックス タイプ
MongoDB には幅広いデータとクエリをサポートできるようにさまざまなインデックス タイプがあります。
シングル フィールド
MongoDB が定義する_id
インデックスに加えて、MongoDBはドキュメントの単一フィールドに対してユーザー定義の昇順および降順インデックスの作成をサポートしています。
単一フィールドインデックスとソート操作の場合、ソート順序( の昇順または降順)は関係ありません。これは、MongoDB がどちらの方向にもインデックスをトラバースできるためです。
単一フィールド インデックスの詳細については、「単一フィールド インデックスと 単一フィールド インデックスによるソート」を参照してください。
複合インデックス
MongoDB では、複数のフィールドに対するユーザー定義のインデックス、つまり複合インデックス もサポートされています。
複合インデックスにリストされるフィールドの順序は重要です。 たとえば、複合インデックスが{ userid: 1, score: -1 }
で構成されている場合、インデックスは最初にuserid
でソートされ、次に 各userid
値内でscore
によってソートされます。
複合インデックスとソート操作の場合、ソート順( 昇順または降順)のインデックス キーによって、インデックスがソート操作をサポートできるかどうかが決まります。 インデックス順序が複合インデックスの結果に与える影響の詳細については、「ソート順序」を参照してください。
以下も参照してください。
Multikey Index
MongoDB は、配列に保存されているコンテンツのインデックス作成にマルチキー インデックスを使用します。 配列値を保持するフィールドをインデックス化すると、MongoDB は配列の一意の要素ごとに個別のインデックスエントリを作成します。 これらのマルチキー インデックスを使用すると、クエリは配列の 1 つまたは複数の要素を照合して、配列を含むドキュメントを選択できます。 MongoDB は、インデックス付きフィールドに配列値が含まれている場合、マルチキー インデックスを作成するかどうかを自動的に決定します。マルチキーのタイプを明示的に指定する必要はありません。
マルチキー インデックスの詳細については、「 マルチキーインデックスと マルチキー インデックスの限界」を参照してください。
地理空間インデックス
地理空間座標データの効率的なクエリをサポートするために、MongoDB には結果を返すときに平面ジオメトリを使用する2d インデックスと、結果を返すために球面ジオメトリを使用する2dsphere インデックスという 2 つの特別なインデックスが用意されています。
このインデックスはsparse indexです。 sparse indexを使用して複合インデックスを作成する場合は、まずスパース 複合インデックスの使用に関する特別な考慮事項を確認してください。
地理空間インデックスの概要については、「 地理空間インデックス」を参照してください。
テキスト検索インデックス
MongoDB Atlas でホストされているデータの場合、Atlas Search インデックスを使用した全文検索をサポートできます。 詳しくは「 Atlas Search インデックスの作成 」を参照してください。
自己管理型(Atlas 以外)の配置の場合、MongoDB はコレクション内の string コンテンツの検索をサポートするtext
インデックス型を提供します。 自己管理型テキストインデックスについて詳しくは、「自己管理型配置のテキストインデックス 」を参照してください。
このインデックスはsparse indexです。 sparse indexを使用して複合インデックスを作成する場合は、まずスパース 複合インデックスの使用に関する特別な考慮事項を確認してください。
ハッシュされたインデックス
ハッシュベースのシャーディングをサポートするために、MongoDB はハッシュされたインデックス型 を提供します。これは、フィールドの値のハッシュをインデックスします。 これらのインデックスは範囲に応じて値のよりランダムな分散を持ちますが、等価一致のみをサポートし、範囲ベースのクエリをサポートすることはできません。
クラスター化インデックス
MongoDB 5.3 以降では、クラスター インデックス付きのコレクションを作成できます。 クラスター化されたインデックスを使用して作成されたコレクションは、クラスター化されたコレクションと呼ばれます。
ワイルドカード インデックス
MongoDB 4.2 以降では、 ワイルドカード インデックス を使用して、複数のフィールド、任意のフィールド、または不明なフィールドに対するクエリをサポートできます。 ワイルドカード インデックスを作成するときは、すべてのフィールドまたはすべての値を表すために$**
を指定するため、1 回の コマンドで次のいずれかをインデックス化できます。
フィールドのすべての値
ドキュメント内のすべてのフィールド
特定のフィールドパスを除くドキュメント内のすべてのフィールド
ドキュメント内の複数の特定フィールド
詳細については、「ワイルドカード インデックス 」を参照してください。
インデックスのプロパティ
Unique Indexes
インデックスの一意のプロパティにより、MongoDB はインデックス フィールドの重複値を拒否します。 一意の制約を除き、一意のインデックスは他の MongoDB インデックスと機能的に互換性があります。
部分インデックス
部分インデックスは、指定されたフィルター式を満たすコレクション内のドキュメントのみをインデックスします。 コレクションのドキュメントのサブセットがインデックス化されるため、ストレージ必要量が少なくなり、インデックスの作成と維持の実行コストが減少します。
部分インデックスは 、スパースインデックスの機能のスーパーセットを提供するため、スパースインデックスよりも優先され、
Sparse Indexes
インデックスのスパースプロパティにより、インデックスには インデックス付きフィールドを持つドキュメントのエントリのみが含まれます。 インデックスは、インデックス付きフィールドがないドキュメントをスキップします。
sparse indexオプションと 一意なインデックス オプションを組み合わせると、インデックス付きフィールドに重複値を持つドキュメントの挿入を防ぎ、インデックス付きフィールドが欠落しているドキュメントのインデックス作成をスキップできます。
TTL Indexes
TTL インデックスは、MongoDB が一定時間の経過後にコレクションからドキュメントを自動的に排除するために使用できる特殊なインデックスです。 これは、一定時間のみデータベースに保持する必要があるタイプのデータには最適です。たとえば、マシンで生成されたイベント データ、ログ、セッション情報はこうしたデータに該当します。
実装手順については、「 TTL を設定してコレクションのデータを期限切れにする」を参照してください。
Hidden Indexes
バージョン 4.4 で追加。
非表示にされたインデックスはクエリ プランナーには表示されず、クエリのサポートに使用することはできません。
プランナーからインデックスを非表示にすることで、ユーザーは実際にインデックスを削除せずに、インデックスを削除した場合の潜在的な影響を評価できます。 影響が悪の場合、ユーザーは削除されたインデックスを再度作成する必要がある代わりに、インデックスを再表示できます。 また、インデックスは非表示になっている間完全に維持されているため、非表示が解除されたらすぐに使用できるようになります。
_id
インデックスを除き、すべてのインデックスを非表示にできます。
インデックスの使用
インデックスを使用すると、読み取り操作の効率を向上させることができます。 「クエリ パフォーマンスの分析 」では、インデックスあり、およびインデックスなしのクエリの実行統計の例が示されています。
MongoDB が使用するインデックスを選択する方法の詳細については、「クエリオプティマイザ 」を参照してください。
インデックスと照合
照合を指定すると、大文字・小文字やアクセント記号など、文字列を比較するための言語独自のルールを指定できます。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
Compass でインデックスを使用してカスタム照合を使用する手順については、 MongoDB Compass ドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
注意
次の例は、 mongosh
のインデックスと照合を示しています。
特定のドライバーで照合を使用してインデックスを作成する手順については、ドライバーのドキュメントを参照してください。
文字列の比較にインデックスを使用するには、操作で同じ照合も指定する必要があります。つまり、照合順序を持つインデックスでは、操作で異なる照合順序が指定されている場合、インデックス付きフィールドで文字列比較を実行する操作をサポートできません。
警告
照合が構成されたインデックスは、並べ替え順序を実現するために ICU 照合キーを使用するため、照合対応のインデックス キーは、照合のないインデックスのインデックス キーよりも大きくなる可能性があります。
たとえば、コレクション myColl
には、照合ロケール "fr"
を持つ文字列フィールド category
のインデックスがあります。
db.myColl.createIndex( { category: 1 }, { collation: { locale: "fr" } } )
インデックスと同じ照合を指定する次のクエリ操作では、インデックスを使用できます。
db.myColl.find( { category: "cafe" } ).collation( { locale: "fr" } )
ただし、デフォルトで「シンプル」なバイナリー コレータを使用する次のクエリ操作では、インデックスを使用できません。
db.myColl.find( { category: "cafe" } )
インデックス プレフィックスキーが文字列、配列、および埋め込みドキュメントではない複合インデックスの場合でも、異なる照合を指定する操作では、インデックスを使用してインデックス プレフィックスキーの比較をサポートできます。
たとえば、myColl
コレクションには、数値フィールドの score
、price
、および 文字列フィールドの category
の複合インデックスがあります。このインデックスは、文字列比較用の照合ロケール "fr"
を使用して作成されます。
db.myColl.createIndex( { score: 1, price: 1, category: 1 }, { collation: { locale: "fr" } } )
文字列の比較に "simple"
バイナリ照合を使用する次の操作では、インデックスを使用できます。
db.myColl.find( { score: 5 } ).sort( { price: 1 } ) db.myColl.find( { score: 5, price: { $gt: NumberDecimal( "10" ) } } ).sort( { price: 1 } )
次の操作では、"simple"
バイナリ照合を使用してインデックス付きの category
フィールドで文字列を比較しますが、クエリの score: 5
部分の実行についてはインデックスが使用できます。
db.myColl.find( { score: 5, category: "cafe" } )
重要
ドキュメント キーとの照合(埋め込みドキュメントのキーを含む)では、単純なバイナリ比較が使用されます。つまり、"foo.bár" のようなキーのクエリは、strength パラメーターに設定した値にかかわらず、キー "foo.bar" と一致しません。
照合の詳細については、照合のリファレンス ページ を参照してください。
次のインデックスは単純なバイナリ比較のみをサポートしており、照合はサポートしていません。
text indexes,
2dインデックス、
geoHaystack indexes.
カバード クエリ
クエリ条件とクエリのプロジェクションにインデックス付きフィールドのみが含まれる場合、MongoDB はドキュメントをスキャンしたりメモリにドキュメントを取り込んだりせずに、インデックスから直接結果を返します。 このようなカバーされたクエリは非常に効率的になる可能性があります。
カバード クエリの詳細については、「カバード クエリ 」を参照してください。
インデックスの交差
MongoDB は、インデックスの共通部分を使用してクエリを実行できます。 複合クエリ条件を指定するクエリの場合、1 つのインデックスがクエリ条件の一部を実行し、別のインデックスがクエリ条件の別の部分を満たすことができる場合、MongoDB は 2 つのインデックスの共通部分を使用してクエリを実行できます。 複合インデックス と インデックス交差 を使用するのどちらがより効率的かは、特定のクエリとシステムによって異なります。
インデックス交差の詳細については、「 インデックス交差 」を参照してください。
制限事項
インデックスには、インデックス キーの長さやコレクションあたりのインデックス数など、特定の制限が適用されます。 詳細については、「インデックスの制限」を参照してください。
その他の考慮事項
インデックスを使用するとクエリのパフォーマンスは向上しますが、インデックスには運用上の考慮事項がいくつかあります。 詳細については、「インデックスの運用上の考慮事項」を参照してください。
インデックスの構築中に、アプリケーションはインデックスが作成されるコレクションへのパフォーマンスの低下や読み取り/書き込みアクセスの制限が発生することがあります。
インデックス構築プロセスの詳細については、「入力済みコレクションでのインデックス構築 」、特に「 レプリケートされた環境でのインデックス構築 」セクションを参照してください。
一部のドライバーは、インデックス順序を指定するために、NumberLong(1)
ではなく1
を使用します。結果として得られるインデックスは同じです。