Overview
このガイドでは、Dpango モデルを使用してMongoDBインデックスを作成する方法を学習できます。インデックスはクエリの効率を向上させ、クエリとドキュメントストレージの追加機能を提供します。
インデックスがないと、 MongoDB はコレクション内のすべてのドキュメントをスキャンして 、クエリに一致するドキュメントを見つける必要があります。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 ただし、クエリに適切なインデックスがある場合、 MongoDB はそのインデックスを使用して検査するドキュメントを制限できます。
Dlango は、モデルにインデックスを作成するために使用できる Indexクラスを提供します。 Dlango MongoDBバックエンドは、モデルが表すMongoDBコレクションに同じインデックスを作成します。
Tip
Indexクラスの詳細については、Diango ドキュメントの Index を参照してください。
サンプル データ
このガイドの例では、nutritionフィールドの値として埋め込み Nutrition モデルを含む Recipe モデルを使用します。 これらのモデル クラスには、次の定義があります。
from django.db import models from django.db.models import Q, F from django_mongodb_backend.models import EmbeddedModel from django_mongodb_backend.fields import EmbeddedModelField, ArrayField from django_mongodb_backend.indexes import SearchIndex, VectorSearchIndex class Nutrition(EmbeddedModel): calories = models.IntegerField(default=0) carb_grams = models.IntegerField(default=0) protein_grams = models.IntegerField(default=0) class Recipe(models.Model): title = models.CharField(max_length=200) cuisine = models.CharField(max_length=200) cook_time = models.IntegerField(default=0) allergens = ArrayField(models.CharField(max_length=100), null=True, blank=True) ratings = ArrayField(models.IntegerField(default=0), size=10) nutrition = EmbeddedModelField(Nutrition, null=True, blank=True) class Meta: db_table = "recipes" def __str__(self): return self.title
Recipe モデルの Metaクラスでは、db_table = "recipes" オプションは、Recipe モデルを recipes と呼ばれるMongoDBコレクションにマッピングするように Diango MongoDBバックエンドに指示します。モデルを使用してMongoDBコレクションを操作する Djangoアプリケーションを作成する方法については、「を使い始める」チュートリアルをご覧ください。
インデックスの作成
モデルにインデックスを作成するには、モデルの Metaクラスで indexes オプションを指定します。 この indexes オプションの値を、次のコードに示すように、作成するインデックスのリストに設定します。
class Meta: indexes = [ models.Index(<first index definition>), models.Index(<second index definition>), # add more indexes here ]
インデックスを定義するには、次の引数を models.Index() メソッドに渡します。
fields:インデックスを作成するフィールドのリストを指定します。 この引数は必須です。name:インデックス名を指定します。 この引数は任意であり、指定しない場合は Diango がインデックス名を自動的に作成します。condition:インデックスを作成するドキュメントのサブセットを指定します。 この引数は任意です。condition引数の詳細については、このガイドの「 部分インデックス 」セクションを参照してください。
データベース移行を適用すると、Diango MongoDBバックエンドはMongoDBコレクションに同じインデックスを作成します。
Tip
データベース移行を作成して適用する方法については、Dpango ドキュメントの移行を参照してください。
このセクションでは、次のインデックスタイプの作成方法を説明します。
単一フィールド インデックス
単一フィールドインデックスは、コレクション内の単一フィールドからの情報を保存します。 デフォルトでは 、すべてのMongoDBコレクションには _idフィールドのインデックスがあります。
次の例では、 Recipe モデルの Metaクラスを更新して titleフィールドに単一のフィールドインデックスを作成します。これによりMongoDBバックエンドは recipesコレクションに作成します。
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title"], name="title_idx"), ]
あるいは、次のコードに示すように、モデルの titleフィールドに db_index オプションを設定して、インデックスを作成することもできます。
class Recipe(models.Model): title = models.CharField(max_length=200, db_index=True)
複合インデックス
複合インデックスは、コレクション内の複数のフィールドからデータを収集してソートします。 MongoDB は、インデックスで指定された最初のフィールドごとにデータをグループ化し、その後は後続のフィールドごとにデータをグループ化します。
次の例では、 Recipe モデルの Metaクラスを更新して title フィールドと cook_time フィールドに複合インデックスを作成します。これによりMongoDBバックエンドは recipesコレクションに作成します。
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["title", "cook_time"]), ]
Multikey Index
マルチキー インデックスは、配列フィールドからデータを収集してソートします。 配列フィールドにインデックスを作成すると、 MongoDB は自動的にそのインデックスをマルチキーインデックスとして設定します。
次の例では、 Recipe モデルの Metaクラスを更新して allergens 配列フィールドに複合インデックスを作成します。これによりMongoDBバックエンドは recipesコレクションに作成します。
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["allergens"], name="allergy_idx"), ]
埋め込みドキュメントインデックス
埋め込みモデル値を保存するフィールドにインデックスを作成できます。埋め込みドキュメントとしてMongoDB は埋め込みドキュメントとして表現します。
次の例では、 Recipe モデルの Metaクラスを更新して nutrition 埋め込みモデルフィールドにインデックスを作成します。このMongoDBは recipesコレクションに作成されます。
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["nutrition"]), ]
重要
前の例で作成されたインデックスは、埋め込みドキュメント全体を指定するクエリでのみ使用されます。 埋め込みドキュメント内の特定のフィールドに対するクエリでは、インデックスは使用されません。 ただし、内部 Metaクラスを Nutrition モデルに追加し、indexes オプションを指定することで、埋め込みドキュメント内のフィールドにインデックスことができます。
高度なインデックス構成
このセクションでは、次の高度なインデックスタイプの作成方法を説明します。
警告
検索インデックスの移行
新しいMongoDB Search またはベクトル検索インデックス を作成し、データベース移行コマンドを実行すると、Diango が移行を適用するまでに時間がかかる場合があります。データの整合性を確保するために、Diango はMongoDB がインデックス操作を完了するまでブロックします。コレクションのサイズに応じて、移行が完了するまでに 秒または 分かかる場合があります。
検索インデックス
MongoDB Search インデックスは、 MongoDBコレクションに対する全文検索であるMongoDB Search クエリの動作を指定します。
検索インデックスを作成するには、モデルの Metaクラスの indexes オプションを SearchIndexオブジェクトに割り当てます。次の引数を任意の順序で SearchIndex() コンストラクターに渡します。
fields:インデックスを作成するフィールド。name:(任意) 検索インデックスの名前。この引数を指定しない場合、Diango はインデックス名を自動的に生成します。
Diango MongoDBバックエンド v5.2.2 以降では、次の引数を SearchIndex() に渡すこともできます。
field_mappings:(任意)フィールド名をインデックスオプションにマッピングする辞書。fieldsの代わりにこの引数を使用して、個々のフィールドに対してインデックス動作を指定する複雑な検索インデックスを作成できます。analyzer:(任意) インデックス作成中に string フィールドに適用するアナライザ。この引数を指定しない場合、 MongoDB Server はデフォルトでlucene.standardになります。search_analyzer:(任意)クエリ テキストに適用するアナライザ。この引数を指定しない場合、その値はanalyzer値と同じになります。両方の引数を省略すると、 MongoDB Server はデフォルトでlucene.standardになります。
Tip
MongoDB Search のクエリとインデックスの詳細については、次のリソースを参照してください。
Atlas ドキュメントの検索インデックス リファレンス
Atlas ドキュメントの検索アナライザ
Diango MongoDBバックエンドAPIドキュメントの SearchIndexクラス
基本的な検索インデックスの例
次の例では、 Recipe モデルの Metaクラスを更新して、titleフィールドに "title_search_idx" という名前の基本検索インデックスを作成します。
class Meta: db_table = "recipes" indexes = [ SearchIndex( fields=["title"], name="title_search_idx", ) ]
高度な検索インデックスの例
次の例では、 cuisineフィールドをtoken 型としてインデックス化し、アナライザをlucene.simple に設定する検索インデックスを作成します。
class Meta: db_table = "recipes" indexes = [ SearchIndex( name="cuisine_search_idx", field_mappings={ "cuisine": { "type": "token" } }, analyzer="lucene.simple" ) ]
Tip
前の例の検索インデックス構成の詳細については、Atlas ドキュメントの次のリソースを参照してください。
ベクトル検索インデックス
MongoDB ベクトル検索インデックスを使用すると、キーワード一致ではなく、セマンティック意味に基づいてデータをクエリできます。ベクトル検索を全文検索クエリとAIフレームワークと統合して、ユースケースの範囲をサポートできます。
ベクトル検索インデックスを作成するには、モデルの Metaクラスの indexes オプションを VectorSearchIndexオブジェクトに割り当てます。次の引数を任意の順序で VectorSearchIndex() コンストラクターに渡します。
name:(任意)ベクトル検索インデックスの名前。この引数を指定しない場合、Diango はインデックス名を自動的に生成します。fields:インデックスを作成するフィールド。少なくとも 1 つは、サイズ のあるFloatFieldまたはIntegerFieldの値の配列で表されるベクトルフィールドである必要があります。similarities: 使用する類似度関数。"cosine"、"dotProduct"、または"euclidean"類似度関数を使用できます。関数は、単一の string 値または個々のベクトルフィールドに関数を割り当てる値のリストとして指定されます。
次の例では、Recipe モデルの Metaクラスを更新して、ratingsベクトルフィールドと cook_time 数値フィールドに "vector_search_idx" という名前のベクトル検索インデックスを作成します。
class Meta: db_table = "recipes" indexes = [ VectorSearchIndex( name=["vector_search_idx"], fields=["ratings", "cook_time"], similarities=["cosine", "euclidean"], ) ]
Tip
ベクトル検索のクエリとインデックスの詳細については、次のリソースを参照してください。
Atlas ドキュメントのベクトル検索 。
Dpango MongoDBバックエンドAPIドキュメントの VectorSearchIndexクラス
部分インデックス
部分インデックスでは、コレクション内の指定フィルター条件を満たすドキュメントのみがインデックス、ストレージ使用量とパフォーマンスのコストが削減されます。
部分インデックスを作成するには、condition 引数を models.Index() メソッドに渡します。 条件値をフィルター条件を含む Qオブジェクトに設定します。 condition 引数を使用する場合は、name 引数も models.Index() に渡す必要があります。
Tip
Q オブジェクトの詳細については、Diango ドキュメントの Q を参照してください。
次の例では、 Recipe モデルの Metaクラスを更新して cuisineフィールドに部分インデックスを作成し、Diango MongoDBバックエンドに cook_time の値が 30 より小さいドキュメントのみをインデックスに指示します。
class Meta: db_table = "recipes" indexes = [ models.Index(fields=["cuisine"], condition=Q(cook_time__lt=30), name="fast_cuisine_idx"), ]
Unique Indexes
一意なインデックス により、インデックス フィールドに重複する値が保存されるのを防ぐことができます。 単一のフィールドでは、一意のインデックスにより、指定されたフィールドに値が最大 1 回表示されるようになります。 複数のフィールドでは、一意なインデックス により、インデックスキー値の任意の組み合わせが最大 1 回表示されるようになります。
単一フィールドの例
次の例では、 Recipe モデルの cuisineフィールド を更新し、unique オプションを True に設定して一意の単一フィールドインデックスを作成します。
cuisine = models.CharField(max_length=200, unique=True)
注意
unique オプションを True に設定すると、指定されたフィールドにインデックスが自動的に作成されます。
複合例
次の例では、 Recipe モデルの Metaクラスを更新して、title フィールドと cuisine フィールドに複合インデックスを作成します。 このコードでは、constraintsオプションを UniqueConstraintインスタンスに設定し、次のフィールドに一意の複合インデックスを作成します。
class Meta: db_table = "recipes" constraints = [ models.UniqueConstraint(fields=["title", "cuisine"], name="unique_regional_meal"), ]
Tip
constraints オプションを UniqueConstraint に設定すると、指定されたフィールドにインデックスが自動的に作成されます。Meta クラスの constraint オプションの詳細については、Dmango ドキュメントの「 制約 」を参照してください。
詳細情報
このガイドで言及されているインデックスの種類の詳細については、次のMongoDB Serverマニュアル リソースを参照してください。
Dlango モデルでのインデックス作成の詳細については、Diango ドキュメントの Index を参照してください。