Docs Menu
Docs Home
/ / /
C#/.NET ドライバー
/

Indexes

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

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

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

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

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

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

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

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

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

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

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

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

MongoDB には、データのクエリをサポートするためにさまざまなインデックス タイプがあります。 以下のセクションでは、最も一般的なインデックス型について説明し、各インデックス型を作成するためのサンプルコードを示します。

注意

これらの例では、sample_mflix.movies sample_mflix.theatersAtlas サンプル データセット の コレクションと コレクションを使用します。無料の MongoDB Atlas クラスターを作成し、サンプル データセットをロードする方法については、 クイック スタートを参照してください。

単一フィールド インデックスは、コレクションのドキュメント内の単一のフィールドを参照するインデックスです。 単一フィールド クエリとソートのパフォーマンスが向上し、一定時間の経過後または特定のクロック時間にコレクションからドキュメントを自動的に排除する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 は、改良された全文検索ソリューションである Atlas Search を提供します。Atlas Search インデックスとその使用方法の詳細については、このガイドの「 Atlas Search とベクトル検索インデックス 」セクションを参照してください。

テキスト インデックスは Atlas Search クエリをサポートできず、Atlas 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 は、 2 dsphere インデックスを使用した地理空間座標データのクエリをサポートしています。 2 dsphere インデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。

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);

MongoDB は、ユークリッド平面上の距離を計算し、「レガシー coordinate pairs」構文を操作するための 2d インデックスもサポートしています。 詳細については、サーバー マニュアルの 地理空間クエリ を参照してください。

一意なインデックスにより、インデックス フィールドに重複する値が保存されなくなります。 デフォルトでは、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);
}

戻る

トランザクション

項目一覧