Docs Menu
Docs Home
/ / /
C#/.NET
/

Indexes

項目一覧

  • Overview
  • クエリ範囲とパフォーマンス
  • 操作上の考慮事項
  • インデックス タイプ
  • 単一フィールド インデックス
  • 複合インデックス
  • Multikey Indexes
  • クラスター化インデックス
  • Atlas Search インデックス
  • Text Indexes
  • 地理空間インデックス
  • Unique Indexes
  • ワイルドカード インデックス
  • インデックスをリストする

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Atlas Search 機能を使用すると、MongoDB Atlas でホストされているコレクションに対して全文検索を実行できます。 インデックスは、検索の動作とインデックスを作成するフィールドを指定します。

MongoDB Atlas Search の詳細については、「 Atlas Search インデックス」のドキュメントを参照してください。

注意

Atlas Search インデックス マネジメントのメソッドは非同期で実行されます。 ドライバー メソッドは、正常に実行されたことを確認する前に戻ることができます。 インデックスの現在のステータスを確認するには、 IMongoSearchIndexManager.List() メソッドを呼び出します。

次のセクションには、Atlas Search インデックスの作成方法と操作方法を示すチュートリアルへのリンクが含まれています。

Atlas コレクションで検索を実行する前に、まずコレクションに Atlas Search インデックスを作成する必要があります。 .NET/C# ドライバーを使用して Atlas Search インデックスを作成する方法については、Atlas マニュアルの「 Atlas Search インデックスの作成」を参照し、言語ドロップダウンから C#を選択します。

.NET/C# ドライバーを使用して Atlas Search インデックスのリストを表示する方法については、Atlas マニュアルの「 Atlas Search インデックスの表示 」を参照し、言語ドロップダウンからC#を選択します。

.NET/C# ドライバーを使用して既存の Atlas Search インデックスを変更する方法については、Atlas マニュアルの「 Atlas Search インデックスの編集 」を参照し、言語ドロップダウンからC#を選択します。

.NET/C# ドライバーを使用して Atlas Search インデックスを削除する方法については、Atlas マニュアルの「 Atlas Search インデックスの削除」を参照し、言語ドロップダウンからC#を選択します。

テキスト インデックスは、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 は、ユークリッド平面上の距離を計算し、MongoDB 2.2以前で使用される「legacy 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);
}

戻る

トランザクション