Overview
このガイドでは、PyMongo でインデックスを使用する方法を学習できます。 インデックスはクエリの効率を向上させ、ドキュメントのクエリと保存に機能を追加します。
インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンして 、各クエリに一致するドキュメントを見つける必要があります。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 ただし、クエリに適切なインデックスがある場合、MongoDB はそのインデックスを使用して検査する必要があるドキュメントを制限できます。
操作上の考慮事項
クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスをビルドします。 追加する各インデックスはアクティブな場合にディスク領域とメモリを消費するため、キャパシティー プランニングとしてインデックス メモリとディスク使用量を追跡することをお勧めします。 さらに、書込み操作によってインデックス付きフィールドがアップデートされると、MongoDB は関連するインデックスをアップデートします。
MongoDB は動的スキーマをサポートしているため、アプリケーションは名前が事前に不明であるか、任意のフィールドであるフィールドに対してクエリを実行できます。ワイルドカード インデックスは、これらのクエリをサポートするのに役立ちます。ワイルドカード インデックスは、ワークロードベースのインデックスプランニングを置き換えるように設計されていません。
データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、 マニュアルの「 データ モデリングとインデックス MongoDB Server」のガイドを参照してください。
サンプル データ
このガイドの例では、 Atlas サンプル データセットの sample_mflix.moviesコレクションを使用します。 無料の MongoDB Atlas クラスターを作成し、サンプル データセットをロードする方法については、 PyMongo を使い始める を参照してください。
インデックス タイプ
単一フィールドと複合インデックス
単一フィールド インデックス
単一フィールド インデックスは、コレクションのドキュメント内の単一のフィールドを参照するインデックスです。 単一フィールド クエリとソートのパフォーマンスが向上し、一定時間の経過後または特定のクロック時間にコレクションからドキュメントを自動的に排除するTTL インデックスをサポートします。
注意
_id_インデックスは、単一フィールド インデックスの例です。 このインデックスは、新しいコレクションが作成されるときに、 _idフィールドに自動的に作成されます。
次の例では、 titleフィールドに昇順のインデックスを作成します。
movies.create_index("title")
以下は、前のコード例で作成されたインデックスによってカバーされるクエリの例です。
query = { "title": "Batman" } sort = [("title", 1)] cursor = movies.find(query).sort(sort)
詳細については、 マニュアルの 「 単一フィールド インデックス 」 を参照してください。MongoDB Server
複合インデックス
複合インデックスは、コレクションのドキュメント内の複数のフィールドへの参照を保持し、クエリとソートのパフォーマンスを向上させます。
次の例では、 フィールドと フィールドに複合インデックスを作成しています。typegenre
movies.create_index([("type", pymongo.ASCENDING), ("genre", pymongo.ASCENDING)])
以下は、前のコード例で作成されたインデックスを使用するクエリの例です。
query = { "type": "movie", "genre": "Drama" } sort = [("type", pymongo.ASCENDING), ("genre", pymongo.ASCENDING)] cursor = movies.find(query).sort(sort)
詳細については、 マニュアルの「 複合インデックス MongoDB Server」を参照してください。
マルチキー インデックス(配列フィールドへのインデックス)
マルチキー インデックスは、配列値を含むインデックスを持つフィールドを指定するクエリのパフォーマンスを向上させるインデックスです。 単一フィールドまたは複合インデックスと同じ構文を使用して、マルチキー インデックスを定義できます。
次の例では、 castフィールドにマルチキー インデックスを作成しています。
result = movies.create_index("cast")
以下は、前のコード例で作成されたインデックスを使用するクエリの例です。
query = { "cast": "Viola Davis" } cursor = movies.find(query)
マルチキー インデックスは、クエリ カバレッジ、インデックスバウンド計算、およびソート動作の点で他のインデックスとは動作が異なります。マルチキー インデックス(動作や制限事項を含む)の詳細については、 MongoDB Serverマニュアルの「 マルチキー インデックス 」ガイドを参照してください。
MongoDB Search とベクトル検索インデックス
PyMongo を使用して、 MongoDB Search およびMongoDB ベクトル検索インデックスを管理できます。インデックスは、検索の動作とインデックスを作成するフィールド を指定します。
MongoDB Search を使用すると、 MongoDB Atlasでホストされているコレクションに対して全文検索を実行できます。 MongoDB Search インデックスは、検索の動作とインデックスを作成するフィールド を指定します。
MongoDB ベクトル検索と、 MongoDB Atlasに保存されているベクトル埋め込みに対してセマンティック検索を実行できます。ベクトル検索インデックスは、ベクトル対象のベクトル埋め込みと、データを事前フィルタリングするために使用するブール値、 date、 objectId、数値、string、または UUID 値のインデックスを定義します。
コレクションに対して次のメソッドを呼び出して、 MongoDB Search およびベクトル検索インデックスを管理できます。
create_search_index()create_search_indexes()list_search_indexes()update_search_index()drop_search_index()
注意
MongoDB Search インデックス マネジメントのメソッドは非同期で実行されます。ドライバー メソッドは、正常に実行されたことを確認する前に戻ることができます。インデックスの現在のステータスを確認するには、list_search_indexes() メソッドを呼び出します。
次のセクションでは、前述の各メソッドの使用方法を示すコード例を示します。
検索インデックスを作成
create_search_index() メソッドと create_search_indexs() メソッドを使用して、 MongoDB Search インデックスまたはMongoDB ベクトル検索インデックスを作成できます。
次のコード例は、 MongoDB Searchインデックスを 1 つ作成する方法を示しています。
index = { "definition": { "mappings": { "dynamic": True } }, "name": "<index name>", } collection.create_search_index(index)
The following code example shows how to create a single MongoDB Vector Search index by using the SearchIndexModel object:
from pymongo.operations import SearchIndexModel search_index_model = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="<index name>", type="vectorSearch", ) collection.create_search_index(model=search_index_model)
create_search_indexs() メソッドを使用して複数のインデックスを作成できます。これらのインデックスは、 MongoDB Search またはベクトル検索インデックスになります。create_search_indexes() メソッドは、作成する各インデックスに対応するSearchIndexModel オブジェクトのリストを受け取ります。
The following code example shows how to create a MongoDB Search index and a MongoDB Vector Search index:
search_idx = SearchIndexModel( definition ={ "mappings": { "dynamic": True } }, name="my_index", ) vector_idx = SearchIndexModel( definition={ "fields": [ { "type": "vector", "numDimensions": <number of dimensions>, "path": "<field to index>", "similarity": "<select from euclidean, cosine, dotProduct>" } ] }, name="my_vector_index", type="vectorSearch", ) indexes = [search_idx, vector_idx] collection.create_search_indexes(models=indexes)
検索インデックスをリストする
list_search_indexs() メソッドを使用して、コレクションのMongoDB Search インデックスとベクトル検索インデックスに関する情報を取得できます。
次のコード例は、コレクションの検索インデックスのリストを出力する方法を示しています。
results = list(collection.list_search_indexes()) for index in results: print(index)
検索インデックスをアップデートする
update_search_index() メソッドを使用して、 MongoDB Search またはベクトル検索インデックス を更新できます。
The following code example shows how to update a MongoDB Search index:
new_index_definition = { "mappings": { "dynamic": False } } collection.update_search_index("my_index", new_index)
The following code example shows how to update a MongoDB Vector Search index:
new_index_definition = { "fields": [ { "type": "vector", "numDimensions": 1536, "path": "<field to index>", "similarity": "euclidean" }, ] } collection.update_search_index("my_vector_index", new_index_definition)
検索インデックスを削除する
drop_search_index() メソッドを使用して、 MongoDB Search またはMongoDB ベクトル検索インデックスを削除できます。
次のコードは、コレクションから検索インデックスを削除する方法を示しています。
collection.drop_search_index("my_index")
Text Indexes
テキスト インデックスは、string コンテンツに対するテキスト検索クエリをサポートします。 これらのインデックスには、値が string または複数の string 配列である任意のフィールドを含めることができます。 MongoDB はさまざまな言語のテキスト検索をサポートしています。 インデックスの作成時に、オプションとしてデフォルト言語を指定できます。
Tip
MongoDB は、改良された全文検索ソリューションであるMongoDB Search を提供します。 MongoDB Search インデックスとその使用方法の詳細については、このページの「MongoDB Search とベクトル検索インデックス 」セクションを参照してください。
単一フィールドのテキストインデックス
次の例では、 plotフィールドに テキスト インデックスを作成しています。
movies.create_index( [( "plot", "text" )] )
以下は、前のコード例で作成されたインデックスを使用するクエリの例です。
query = { "$text": { "$search": "a time-traveling DeLorean" } } cursor = movies.find(query)
複数のフィールドのテキストインデックス
コレクションには 1 つのテキスト インデックスのみを含めることができます。 複数のテキストフィールドのテキストインデックスを作成する場合は、複合インデックスを作成します。 複合インデックス内のすべてのテキスト フィールドに対してテキスト検索が実行されます。
次の例では、 フィールドと フィールドの複合テキストtitle genreインデックスを作成します。
result = myColl.create_index( [("title", "text"), ("genre", "text")], default_language="english", weights={ "title": 10, "genre": 3 } )
詳細については、 マニュアルの「 複合テキストインデックスの制限 」と「 テキストインデックスMongoDB Server 」を参照してください。
地理空間インデックス
MongoDB は、 2 dsphere インデックスを使用した地理空間座標データのクエリをサポートしています。 2dsphereインデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。 地理空間データのクエリの詳細については、「地理空間クエリ 」を参照してください。
2dsphereインデックスを作成するには、 GeoJSON オブジェクトのみを含むフィールドを指定する必要があります。 これについて詳しくは、 マニュアルの「GeoJSON オブジェクト ガイドMongoDB Server 」を参照してください。
sample_mflixデータベース内のtheatersコレクションの次のサンプル ドキュメントのlocation.geoフィールドは、劇場の座標を記述する GeoJSON ポイント オブジェクトです。
{ "_id" : ObjectId("59a47286cfa9a3a73e51e75c"), "theaterId" : 104, "location" : { "address" : { "street1" : "5000 W 147th St", "city" : "Hawthorne", "state" : "CA", "zipcode" : "90250" }, "geo" : { "type" : "Point", "coordinates" : [ -118.36559, 33.897167 ] } } }
地理空間インデックスの作成
次の例では、 location.geoフィールドに2dsphereインデックスを作成します。
theaters.create_index( [( "location.geo", "2dsphere" )] )
MongoDB は、ユークリッド平面上の距離を計算し、MongoDB 2.2以前で使用される「legacy coordinate pairs」構文を操作するための2dインデックスもサポートしています。 詳細については、 マニュアルの「 地理空間クエリ 」ガイド MongoDB Serverを参照してください。
Unique Indexes
一意なインデックス により、インデックス フィールドに重複する値が保存されなくなります。 デフォルトでは、MongoDB はコレクションの作成中に_idフィールドに一意のインデックスを作成します。 一意のインデックスを作成するには、次の手順を実行します。
重複を防ぐフィールドまたはフィールドの組み合わせを指定します。
uniqueオプションを ``True`` に設定します。
ユニークインデックスの作成
次の例では、 theaterIdフィールドに降順の一意のインデックスを作成しています。
theaters.create_index("theaterId", unique=True)
ワイルドカード インデックス
ワイルドカード インデックスを使用すると、不明なフィールドや任意のフィールドに対するクエリが可能になります。 動的スキーマを使用している場合は、これらのインデックスが役立ちます。
ワイルドカード インデックスの作成
次の例では、サブドキュメントや配列にネストされた値を含む、 locationフィールドのすべての値に対して昇順のワイルドカード インデックスを作成します。
movies.create_index({ "location.$**": pymongo.ASCENDING })
詳細については、MongoDB Server マニュアルの「 ワイルドカード インデックス 」のページを参照してください。
クラスター化インデックス
クラスター化されたインデックスは、キー値の順にドキュメントを保存するようにコレクションに指示します。 クラスター化インデックスを作成するには、コレクションを作成するときに次の手順を実行します。
_idフィールドをキーとして クラスター化インデックス オプション を指定します。一意のフィールドを
Trueに設定します。
クラスター化インデックスの作成
次の例では、新しいmovie_reviewsコレクションの_idフィールドにクラスター化インデックスを作成しています。
sample_mflix.create_collection("movies", clusteredIndex={ "key": { "_id": 1 }, "unique": True })
詳細については、 マニュアルの 「 クラスター化インデックス 」 と 「 クラスター化コレクション」 MongoDB Serverのセクションを参照してください。
インデックスを削除する
_idフィールドのデフォルトの一意なインデックスを除く未使用のインデックスを削除できます。
次のセクションでは、単一のインデックスを削除する方法またはコレクション内のすべてのインデックスを削除する方法を示します。
単一インデックスを排除する
インデックスのインスタンスまたはインデックス名をdrop_index()メソッドに渡して、コレクションからインデックスを削除します。
次の例では、 moviesコレクションから"_title_"という名前のインデックスを削除します。
movies.drop_index("_title_")
注意
複合テキスト インデックスから単一のフィールドを削除することはできません。 インデックス フィールドを更新するには、インデックス全体を削除し、新しいインデックスを作成する必要があります。
すべてのインデックスを削除する
MongoDB 4.2 以降では、コレクションでdrop_indexes()メソッドを呼び出すことで、すべてのインデックスを削除できます。
collection.drop_indexes()
以前のバージョンの MongoDB の場合は、コレクションでdrop_index()を呼び出すパラメータとして"*"を渡します。
collection.drop_index("*")
トラブルシューティング
DuplicateKeyException
一意なインデックスに違反する重複値を保存する書込み操作を実行すると、ドライバーはDuplicateKeyExceptionを発生させ、MongoDB は次のようなエラーを返します。
E11000 duplicate key error index
詳細情報
MongoDBのインデックスの詳細については、 MongoDB Serverマニュアルの「 インデックス ガイド 」を参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。