Indexes
項目一覧
Overview
このガイドでは、MongoDB .NET/C# ドライバーでインデックスを使用する方法を学習できます。 インデックスはクエリの効率を向上させ、ドキュメントのクエリと保存に機能を追加します。
インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンして 、各クエリに一致するドキュメントを見つける必要があります。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 ただし、クエリに適切なインデックスがある場合、MongoDB はそのインデックスを使用して検査する必要があるドキュメントを制限できます。
クエリ範囲とパフォーマンス
MongoDB に対してクエリを実行する場合、クエリにはさまざまな要素を含めることができます。
検索するフィールドと値を指定するクエリ条件
読み取り保証など、クエリの実行に影響するオプション
MongoDB が返すフィールドを指定するためのプロジェクション基準
MongoDB から返されるドキュメントの順序を指定するためのソート基準
クエリ、プロジェクション、ソートで指定されたすべてのフィールドが同じインデックスにある場合、MongoDB はそのインデックスから直接結果を返します。これはカバード クエリとも呼ばれます。
インデックスがクエリ条件とプロジェクションをカバーするようにする方法の詳細については、MongoDB サーバー マニュアルの対象クエリセクションを参照してください。
操作上の考慮事項
クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスを構築します。追加する各インデックスは、アクティブになるとディスク容量とメモリを消費するため、キャパシティプランニングのためにインデックスメモリとディスク使用量を追跡する必要がある場合があります。さらに、書込み操作によってインデックス付きフィールドが更新されると、MongoDB は関連するインデックスも更新します。
MongoDB は動的スキーマをサポートしているため、アプリケーションは名前が事前に確認できないフィールドや任意のフィールドに対してクエリを実行できます。 MongoDB 4.2では、これらのクエリをサポートするためにワイルドカード インデックスが導入されています。 ワイルドカード インデックスは、ワークロードベースのインデックス プランニングを置き換えるように設計されていません。
データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、サーバーのドキュメントの「インデックス作成戦略」と「データ モデリングとインデックス 」を参照してください。
インデックス タイプ
MongoDB には、データのクエリをサポートするためにさまざまなインデックス タイプがあります。 以下のセクションでは、最も一般的なインデックス型について説明し、各インデックス型を作成するためのサンプルコードを示します。
注意
これらの例では、sample_mflix.movies
sample_mflix.theaters
Atlas サンプル データセット の コレクションと コレクションを使用します。無料の 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
rated
sample_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 });
詳細については、サーバー マニュアルの 「クラスター化インデックスとクラスター化コレクション」を参照してください。
Atlas Search インデックス
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#を選択します。
Text Indexes
テキスト インデックスは、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
genre
sample_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
インデックスもサポートしています。 詳細については、サーバー マニュアルの 「地理空間クエリ」 を参照してください。
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); }