Overview
このガイドでは、MongoDB .NET/C# ドライバーでインデックスを使用する方法を学習できます。 インデックスはクエリの効率を向上させ、ドキュメントのクエリと保存に機能を追加します。
インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンして 、各クエリに一致するドキュメントを見つける必要があります。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 ただし、クエリに適切なインデックスがある場合、MongoDB はそのインデックスを使用して検査する必要があるドキュメントを制限できます。
クエリ範囲とパフォーマンス
MongoDB に対してクエリを実行する場合、クエリにはさまざまな要素を含めることができます。
検索するフィールドと値を指定するクエリ条件
読み取り保証など、クエリの実行に影響するオプション
MongoDB が返すフィールドを指定するためのプロジェクション基準
MongoDB から返されるドキュメントの順序を指定するためのソート基準
クエリ、プロジェクション、ソートで指定されたすべてのフィールドが同じインデックスにある場合、MongoDB はそのインデックスから直接結果を返します。これはカバード クエリとも呼ばれます。
インデックスがクエリ条件とプロジェクションをカバーするようにする方法の詳細については、MongoDB サーバー マニュアルの対象クエリセクションを参照してください。
操作上の考慮事項
クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスを構築します。追加する各インデックスは、アクティブになるとディスク容量とメモリを消費するため、キャパシティプランニングのためにインデックスメモリとディスク使用量を追跡する必要がある場合があります。さらに、書込み操作によってインデックス付きフィールドが更新されると、MongoDB は関連するインデックスも更新します。
MongoDB は動的スキーマをサポートしているため、アプリケーションは名前が事前に確認できないフィールドや任意のフィールドに対してクエリを実行できます。ワイルドカード インデックスはこれらのクエリをサポートするのに役立ちますが、ワークロードベースのインデックスプランニングを置き換えるように設計されていません。
データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、サーバーのドキュメントの「インデックス作成戦略」と「データ モデリングとインデックス 」を参照してください。
インデックス タイプ
MongoDB には、データのクエリをサポートするためにさまざまなインデックスタイプがあります。次の手順では、インデックスを作成するためのプロセスを説明します。
Builders<TDocument>.IndexKeysプロパティからアクセスできるIndexKeysDefinitionBuilder<TDocument>クラスを使用して、1 つ以上のIndexKeysDefinition<TDocument>オブジェクトを作成します。これらのキー定義は、作成するインデックスのタイプと、インデックスのその他のプロパティを記述します。新しい
CreateIndexModel<TDocument>オブジェクトを作成します。前のステップのキー定義を コンストラクターに渡します。コレクションの
IndexesプロパティでCreateOne()メソッドを呼び出します。前のステップのCreateIndexModel<TDocument>オブジェクトを渡します。
以下のセクションでは、最も一般的なインデックス型について説明し、各インデックス型を作成するためのサンプルコードを示します。
注意
このページの例では、Atlasサンプルデータセット の sample_mflix.movies コレクションと sample_mflix.theaters コレクションを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 「 .NET/ C#ドライバーを使い始める 」を参照してください。
単一フィールド インデックス
単一フィールド インデックスは、コレクションのドキュメント内の単一のフィールドを参照するインデックスです。 単一フィールド クエリとソートのパフォーマンスが向上し、一定時間の経過後または特定のクロック時間にコレクションからドキュメントを自動的に排除するTTL インデックスをサポートします。
注意
_id_インデックスは、単一フィールド インデックスの例です。 このインデックスは、新しいコレクションが作成されるときに、 _idフィールドに自動的に作成されます。
次の例では、 sample_mflix.moviesコレクション内のtitleフィールドに昇順でインデックスを作成します。
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys.Ascending(m => m.Title)); collection.Indexes.CreateOne(indexModel);
以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。
// Define query parameters var filter = Builders<Movie>.Filter.Eq(m => m.Title, "Batman"); var sort = Builders<Movie>.Sort.Ascending(m => m.Title); var projection = Builders<Movie>.Projection.Include(m => m.Title).Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
詳細については、サーバー マニュアルの「単一フィールド インデックス」を参照してください。
複合インデックス
複合インデックスは、コレクションのドキュメント内の複数のフィールドへの参照を保持し、クエリとソートのパフォーマンスを向上させます。
次の例では、type ratedsample_mflix.moviesコレクション内の フィールドと フィールドに複合インデックスを作成しています。
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Ascending(m => m.Type) .Ascending(m => m.Rated)); collection.Indexes.CreateOne(indexModel);
以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。
// Define query parameters var typeFilter = Builders<Movie>.Filter.Eq(m => m.Type, "movie"); var ratedFilter = Builders<Movie>.Filter.Eq(m => m.Rated, "G"); var filter = Builders<Movie>.Filter.And(typeFilter, ratedFilter); var sort = Builders<Movie>.Sort.Ascending(m => m.Type).Ascending(m => m.Rated); var projection = Builders<Movie>.Projection .Include(m => m.Type) .Include(m => m.Rated) .Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
詳細については、サーバー マニュアルの「複合インデックス」を参照してください。
Multikey Indexes
マルチキー インデックスは、配列値を含むフィールドからデータを収集してソートします。 単一フィールドまたは複合インデックスと同じ構文を使用してマルチキー インデックスを定義できます。
次の例では、 sample_mflix.moviesコレクション内のrated 、 genres (文字列の配列)、 titleフィールドに複合マルチキー インデックスを作成します。
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Ascending(m => m.Rated) .Ascending(m => m.Genres) .Ascending(m => m.Title)); collection.Indexes.CreateOne(indexModel);
以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。
// Define query parameters var genreFilter = Builders<Movie>.Filter.AnyEq(m => m.Genres, "Animation"); var ratedFilter = Builders<Movie>.Filter.Eq(m => m.Rated, "G"); var filter = Builders<Movie>.Filter.And(genreFilter, ratedFilter); var sort = Builders<Movie>.Sort.Ascending(m => m.Title); var projection = Builders<Movie>.Projection .Include(m => m.Title) .Include(m => m.Rated) .Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Sort(sort).Project(projection);
マルチキー インデックスは、クエリ カバレッジ、インデックスバウンド計算、およびソート動作の点で他のインデックスとは動作が異なります。 マルチキー インデックス(動作や制限事項を含む)の詳細については、サーバー マニュアルの「 マルチキー インデックス 」のページを参照してください。
クラスター化インデックス
クラスター化されたインデックスは、キー値の順にドキュメントを保存するようにコレクションに指示します。クラスター化インデックスを作成するには、コレクションを作成する ときに、_idフィールドをキーとして指定し、Uniqueプロパティをtrue として指定して、 クラスター化インデックスオプション を指定します。コレクションには、単一の クラスター化インデックスのみを含めることができます。クラスターインデックスを作成するには、コレクションを作成する ときに指定します。
次の例では、新しいsample_mflix.reviewsコレクションを作成する際に、 _idフィールドにクラスター化インデックスを作成します。
var database = mongoClient.GetDatabase("sample_mflix"); var clusteredIndexOptions = new ClusteredIndexOptions<Review> { Key = Builders<Review>.IndexKeys.Ascending(r => r.Id), Unique = true }; database.CreateCollection("reviews", new CreateCollectionOptions<Review> { ClusteredIndex = clusteredIndexOptions });
詳細については、サーバー マニュアルの 「クラスター化インデックスとクラスター化コレクション」を参照してください。
Text Indexes
テキスト インデックスは、string コンテンツに対するテキスト検索クエリをサポートします。 これらのインデックスには、値が string または複数の string 配列である任意のフィールドを含めることができます。 MongoDB はさまざまな言語のテキスト検索をサポートしています。 インデックスの作成時に、オプションとしてデフォルト言語を指定できます。
Tip
MongoDB は、改良された全文検索ソリューションであるMongoDB Searchを提供します。MongoDB Search 検索インデックスとその使用方法の詳細については、このガイドのMongoDB Search と MongoDB ベクトル検索インデックスセクションを参照してください。
テキストインデックスはMongoDB Search クエリをサポートできず、 MongoDB Search インデックスはテキストクエリをサポートできないことに注意してください。
シングル フィールド
次の例では、 sample_mflix.moviesコレクション内のplotフィールドにテキスト インデックスを作成しています。
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys.Text(m => m.Plot)); collection.Indexes.CreateOne(indexModel);
次のクエリは、前のコード スニペットで作成されたテキスト インデックスを使用します。
// Define query parameters var filter = Builders<Movie>.Filter.Text("java coffee shop"); var projection = Builders<Movie>.Projection.Include(m => m.Plot).Exclude(m => m.Id); // Execute query var results = collection.Find(filter).Project(projection);
複数のフィールド
コレクションには1 つの テキストインデックスのみを含めることができます。複数のテキストフィールドのテキストインデックスを作成するには、複合インデックスを作成する必要があります。複合インデックス内のすべてのテキスト フィールドに対してテキスト検索が実行されます。
次のスニペットは、title genresample_mflix.moviesコレクション内の フィールドと フィールドの複合テキスト インデックスを作成します。
var indexModel = new CreateIndexModel<Movie>(Builders<Movie>.IndexKeys .Text(m => m.Title) .Text(m => m.Genre)); collection.Indexes.CreateOne(indexModel);
詳細については、サーバー マニュアルの「複合テキスト インデックスの制限とテキスト インデックス」を参照してください。
地理空間インデックス
MongoDBでは、 2d または 2dsphere インデックスを使用して地理空間座標データをクエリできます。
2dsphere インデックス
2dsphere インデックスは、地球のような球体上の地理空間クエリをサポートします。2dsphereインデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。インデックスフィールドはGeoJSON オブジェクト またはレガシー coordinate pairs のいずれかである必要があります。
2 dsphere インデックスを作成するには、 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インデックスを作成します。
重要
すでに地理空間インデックスでカバーされているフィールドに地理空間インデックスを作成しようとすると、エラーが発生します。
var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Geo2DSphere(t => t.Location.Geo)); collection.Indexes.CreateOne(indexModel);
以下は、「location.geo」を使用した地理空間クエリの例です。 インデックス:
// Stores the coordinates of the NY MongoDB headquarters var refPoint = GeoJson.Point(GeoJson.Position(-73.98456, 40.7612)); // Creates a filter to match documents that represent locations up to 1000 meters from the specified point directly from the geospatial index var filter = Builders<Theater>.Filter.Near(m => m.Location.Geo, refPoint, 1000.0, 0.0); // Execute the query var results = collection.Find(filter);
2d Indexes
.NET/ C#ドライバーには、2d インデックスを作成するための Geo2D メソッドも含まれています。これらのインデックスを使用して、ユークリッド平面上の距離を計算したり、 MongoDB 2.2 以前で使用される " レガシー coordinate pairs"構文を使用できます。 詳細については、サーバー マニュアルの 「地理空間クエリ」 を参照してください。
Unique Indexes
一意なインデックスにより、インデックス フィールドに重複する値が保存されなくなります。 デフォルトでは、MongoDB はコレクションの作成中に_idフィールドに一意のインデックスを作成します。 一意のインデックスを作成するには、重複を防ぐフィールドを指定し、 Uniqueオプションをtrueに設定します。
次の例では、 sample_mflix.theatersコレクション内のtheaterIdフィールドに一意の降順インデックスを作成しています。
var options = new CreateIndexOptions { Unique = true }; var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Descending(t => t.TheaterId), options); collection.Indexes.CreateOne(indexModel);
ユニークインデックスに違反する重複値を格納する書込み操作を実行しようとすると、MongoDB は次のようなエラーを返します。
E11000 duplicate key error index
詳細については、サーバー マニュアルの 「一意なインデックス」 を参照してください。
ワイルドカード インデックス
ワイルドカード インデックスを使用すると、不明なフィールドや任意のフィールドに対するクエリが可能になります。 動的スキーマを使用している場合は、これらのインデックスが役立ちます。
次の例では、サブドキュメントや配列にネストされた値を含む、 sample_mflix.theatersコレクション内のlocationフィールドのすべての値に対して昇順のワイルドカード インデックスを作成します。
var indexModel = new CreateIndexModel<Theater>(Builders<Theater>.IndexKeys.Wildcard(t => t.Location)); collection.Indexes.CreateOne(indexModel);
詳細については、サーバー マニュアルの「ワイルドカード インデックス」のページを参照してください。
インデックスをリストする
List() メソッドを使用して、コレクション内のインデックスのリストを取得できます。
次の例では、 List()メソッドを使用して、コレクション内のすべてのインデックスを一覧表示します。
var indexes = collection.Indexes.List(); foreach (var index in indexes.ToList()) { Console.WriteLine(index); }
インデックスを削除する
DropOne() メソッドを使用して、コレクションから単一のインデックスを除くことができます。コレクションからすべてのインデックスを除くには、DropAll() メソッドを使用します。
次の例では、DropOne() メソッドを使用して、コレクションから "test_index"インデックスを除きます。
collection.Indexes.DropOne("test_index");
次の例では、DropAll() メソッドを使用して、コレクションからすべてのインデックスを除きます。
collection.Indexes.DropAll();
詳細情報
このページで使用されるクラスとメソッドの詳細については、次のAPIドキュメントを参照してください。