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