Docs Menu

Indexes

このガイドでは、PyMongo でインデックスを使用する方法を学習できます。 インデックスはクエリの効率を向上させ、ドキュメントのクエリと保存に機能を追加します。

インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンして 、各クエリに一致するドキュメントを見つける必要があります。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 ただし、クエリに適切なインデックスがある場合、MongoDB はそのインデックスを使用して検査する必要があるドキュメントを制限できます。

クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスをビルドします。 追加する各インデックスはアクティブな場合にディスク領域とメモリを消費するため、キャパシティー プランニングとしてインデックス メモリとディスク使用量を追跡することをお勧めします。 さらに、書込み操作によってインデックス付きフィールドがアップデートされると、MongoDB は関連するインデックスをアップデートします。

MongoDB は動的スキーマをサポートしているため、アプリケーションは名前が事前に不明であるか、任意のフィールドであるフィールドに対してクエリを実行できます。 MongoDB 4.2では、これらのクエリをサポートするためにワイルドカード インデックスが導入されています。 ワイルドカード インデックスは、ワークロードベースのインデックス プランニングを置き換えるように設計されていません。

データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、 マニュアルの「 データ モデリングとインデックス 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マニュアルのマルチキー インデックスガイドを参照してください。

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 インデックスを1つ作成する方法を示しています。

index = {
"definition": {
"mappings": {
"dynamic": True
}
},
"name": "<index name>",
}
collection.create_search_index(index)

次のコード例は、SearchIndexModel オブジェクトを使用して Atlas Vector Search インデックスを 1 つ作成する方法を示しています。

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_indexes() メソッドを使用して、複数のインデックスを作成できます。これらのインデックスは、Atlas Search または Atlas Vector Search インデックスになります。create_search_indexes() メソッドは、作成したい各インデックスに対応する SearchIndexModel オブジェクトのリストを取ります。

次のコード例は、Atlas Search インデックスと Atlas Vector Search インデックスを作成する方法を示しています。

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_indexes() メソッドを使用して、コレクションの Atlas Search インデックスと Atlas Vector Search インデックスに関する情報を取得できます。

次のコード例は、コレクションの検索インデックスのリストを出力する方法を示しています。

results = list(collection.list_search_indexes())
for index in results:
print(index)

update_search_index() メソッドを使用して、Atlas Search インデックスまたは Atlas Vector Search インデックスを更新できます。

次のコード例は、Atlas Search インデックスを更新する方法を示しています。

new_index_definition = {
"mappings": {
"dynamic": False
}
}
collection.update_search_index("my_index", new_index)

次のコード例は、Atlas Vector Search インデックスを更新する方法を示しています。

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() メソッドを使用して、Atlas Search インデックスまたは Atlas Vector Search インデックスを削除できます。

次のコードは、コレクションから検索インデックスを削除する方法を示しています。

collection.drop_search_index("my_index")

テキスト インデックスは、string コンテンツに対するテキスト検索クエリをサポートします。 これらのインデックスには、値が string または複数の string 配列である任意のフィールドを含めることができます。 MongoDB はさまざまな言語のテキスト検索をサポートしています。 インデックスの作成時に、オプションとしてデフォルト言語を指定できます。

Tip

MongoDB は、改良された全文検索ソリューションである Atlas Search を提供します。 Atlas Search インデックスとその使用方法の詳細については、このページの「Atlas 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を参照してください。

一意なインデックス により、インデックス フィールドに重複する値が保存されなくなります。 デフォルトでは、MongoDB はコレクションの作成中に_idフィールドに一意のインデックスを作成します。 一意のインデックスを作成するには、次の手順を実行します。

  • 重複を防ぐフィールドまたはフィールドの組み合わせを指定します。

  • uniqueオプションを ``True`` に設定します。

次の例では、 theaterIdフィールドに降順の一意のインデックスを作成しています。

theaters.create_index("theaterId", unique=True)

詳細については、MongoDB Server マニュアルの 「 一意なインデックス 」 のガイドを参照してください。

ワイルドカード インデックスを使用すると、不明なフィールドや任意のフィールドに対するクエリが可能になります。 動的スキーマを使用している場合は、これらのインデックスが役立ちます。

次の例では、サブドキュメントや配列にネストされた値を含む、 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を発生させ、MongoDB は次のようなエラーを返します。

E11000 duplicate key error index

MongoDBのインデックスの詳細については、 MongoDB Serverマニュアルの「 インデックス ガイド 」を参照してください。

このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。