Docs Menu
Docs Home
/ /

インデックスの作成と管理

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

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

MongoDB に対してクエリを実行する場合、クエリにはさまざまな要素を含めることができます。

  • 検索するフィールドと値を指定するクエリ条件

  • 読み取り保証など、クエリの実行に影響するオプション

  • MongoDB が返すフィールドを指定するためのプロジェクション基準

  • MongoDB から返されるドキュメントの順序を指定するためのソート基準

クエリ、プロジェクション、ソートで指定されたすべてのフィールドが同じインデックスにある場合、MongoDB はそのインデックスから直接結果を返します。これはカバード クエリとも呼ばれます。

インデックスがクエリ条件とプロジェクションをカバーするようにする方法の詳細については、MongoDB サーバー マニュアルの対象クエリセクションを参照してください。

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

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

データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、サーバーのドキュメントの「インデックス作成戦略」と「データ モデリングとインデックス 」を参照してください。

MongoDB には、データのクエリをサポートするためにさまざまなインデックスタイプがあります。次の手順では、インデックスを作成するためのプロセスを説明します。

  1. Builders<TDocument>.IndexKeysプロパティからアクセスできる IndexKeysDefinitionBuilder<TDocument>クラスを使用して、1 つ以上の IndexKeysDefinition<TDocument> オブジェクトを作成します。これらのキー定義は、作成するインデックスのタイプと、インデックスのその他のプロパティを記述します。

  2. 新しい CreateIndexModel<TDocument>オブジェクトを作成します。前のステップのキー定義を コンストラクターに渡します。

  3. コレクションの 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);

詳細については、サーバー マニュアルの「複合インデックス」を参照してください。

マルチキー インデックスは、配列値を含むフィールドからデータを収集してソートします。 単一フィールドまたは複合インデックスと同じ構文を使用してマルチキー インデックスを定義できます。

次の例では、 sample_mflix.moviesコレクション内のratedgenres (文字列の配列)、 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
});

詳細については、サーバー マニュアルの 「クラスター化インデックスクラスター化コレクション」を参照してください。

テキスト インデックスは、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インデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。インデックスフィールドは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);

.NET/ C#ドライバーには、2d インデックスを作成するための Geo2D メソッドも含まれています。これらのインデックスを使用して、ユークリッド平面上の距離を計算したり、 MongoDB 2.2 以前で使用される " レガシー coordinate pairs"構文を使用できます。 詳細については、サーバー マニュアルの 「地理空間クエリ」 を参照してください。

一意なインデックスにより、インデックス フィールドに重複する値が保存されなくなります。 デフォルトでは、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ドキュメントを参照してください。

戻る

LINQ

項目一覧