Overview
インデックスは MongoDB でクエリの効率的な実行をサポートするデータ構造です。クエリをより効率的にするために、ドキュメント内のデータの一部のコピーが含まれています。
インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンして、各クエリに一致するドキュメントを見つける必要があります。これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を及ぼす可能性があります。インデックスを使用して MongoDB がスキャンするドキュメントの数を制限すると、クエリがより効率的になり、結果が早く返されます。
クエリ範囲とパフォーマンス
MongoDB に対してクエリを実行する場合、クエリには次の 3 つの部分を含めることができます。
検索する 1 つ以上のフィールドと値を指定するクエリ条件
読み取り保証など、クエリの実行に影響するオプション
MongoDB が返すフィールドを指定するためのプロジェクション基準(任意)
クエリ条件とクエリのプロジェクションで指定されたすべてのフィールドにインデックスが付けられると、MongoDB はコレクション内のドキュメントをスキャンしたりメモリにロードしたりせずに、インデックスから直接結果を返します。
インデックスがクエリ条件とプロジェクションをカバーするようにする方法について詳しくは、MongoDB マニュアルの「クエリ カバレッジ」と「インデックスの交差」に関する記事を参照してください。
操作上の考慮事項
クエリのパフォーマンスを向上させるには、ソートされた結果を返すアプリケーションのクエリや操作で頻繁に表示されるフィールドにインデックスを構築します。追加する各インデックスは、アクティブになるとディスク容量とメモリを消費するため、キャパシティプランニングのためにインデックスメモリとディスク使用量を追跡する必要がある場合があります。さらに、書込み操作によってインデックス付きフィールドが更新されると、MongoDB は関連するインデックスも更新します。
データモデルの設計とアプリケーションに適したインデックスの選択について詳しくは、MongoDB サーバーのドキュメントの「インデックスの作成戦略」と「データ モデリングとインデックス」を参照してください。
インデックスをリストする
listIndexes() メソッドを使用して、コレクションのすべてのインデックスを一覧表示できます。listIndexes() メソッドでは、任意の ListIndexesOptions パラメーターが使われます。listIndexes() メソッドでは、ListIndexesCursor 型のオブジェクトが返されます。
次のコードを使用することで、 listIndexes() メソッドで、コレクション内のすべてのインデックスが一覧表示されます。
// List the indexes on the collection and output them as an array const result = await collection.listIndexes().toArray(); // Print the list of indexes console.log("Existing indexes:\n"); for(const doc in result){ console.log(doc); }
インデックス タイプ
MongoDB は、データのクエリをサポートするためにいくつかの異なるインデックス型をサポートしています。以下のセクションでは、最も一般的なインデックス型について説明し、各インデックス型を作成するためのサンプルコードを示します。
単一フィールド インデックス
単一フィールド インデックスは、ドキュメントの単一フィールドに対して昇順または降順の並べ替え順序を指定するクエリのパフォーマンスを向上させるインデックスです。
次の例では、createIndex() メソッドを使用して、sample_mflix データベースの movies コレクションの title フィールドに昇順のインデックスが作成されます。
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create an ascending index on the "title" field in the // "movies" collection. const result = await movies.createIndex({ title: 1 }); console.log(`Index created: ${result}`);
以下は、上記で作成したインデックスによってカバーされるクエリの例です。
// Define the query parameters const query = { title: "Batman" } const sort = { title: 1 }; const projection = { _id: 0, title: 1 }; // Execute the query using the defined parameters const cursor = movies .find(query) .sort(sort) .project(projection);
詳細については、「単一フィールド インデックス 」を参照してください。
複合インデックス
複合インデックスは、ドキュメントの 複数の フィールドに対して昇順または降順の並べ替え順序を指定するクエリのパフォーマンスを向上させるインデックスです。インデックスの各フィールドの方向(昇順または降順)を指定する必要があります。
次の例では、createIndex()メソッドを使用して、 sample_mflixデータベースのmoviesコレクション内のtypeフィールドとgenreフィールドに複合インデックスが作成されます。
// Connect to the "sample_mflix" database const database = client.db("sample_mflix"); // Access the database's "movies" collection const movies = database.collection("movies"); // Create an ascending index on the "type" and "genre" fields // in the "movies" collection. const result = await movies.createIndex({ type: 1, genre: 1 }); console.log(`Index created: ${result}`);
以下は、上記で作成したインデックスによってカバーされるクエリの例です。
// Define a query to find movies in the "Drama" genre const query = { type: "movie", genre: "Drama" }; // Define sorting criteria for the query results const sort = { type: 1, genre: 1 }; // Include only the type and genre fields in the query results const projection = { _id: 0, type: 1, genre: 1 }; // Execute the query using the defined criteria and projection const cursor = movies .find(query) .sort(sort) .project(projection);
詳細については、「複合インデックス 」を参照してください。
マルチキー インデックス(配列フィールドへのインデックス)
マルチキー インデックスは、配列値を含むフィールドに対するクエリのパフォーマンスを向上させるインデックスです。
createIndex() メソッドを呼び出すと、配列値を持つフィールドにマルチキー インデックスを作成できます。次のコードを使用することで、sample_mflix データベースの movies0 コレクションの cast フィールドに昇順インデックスが作成されます。
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create a multikey index on the "cast" field in the "movies" collection const result = await movies.createIndex({ cast: 1 });
次のコードを使用することで、マルチキー インデックスをクエリして、cast フィールド値に "Viola Davis" が含まれているドキュメントを検索できます。
const query = { cast: "Viola Davis" }; const projection = { _id: 0, cast: 1 , title: 1 }; // Perform a find operation with the preceding filter and projection const cursor = movies .find(query) .project(projection);
マルチキー インデックスは、クエリ カバレッジ、インデックスバウンド計算、およびソート動作の点で非マルチキーインデックスとは動作が異なります。マルチキー インデックス(動作や制限事項を含む)について詳しくは、MongoDB サーバー マニュアルの「マルチキー インデックス」のページを参照してください。
クラスター化インデックス
クラスター化インデックスは、クラスター化コレクションに対する挿入、アップデート、削除操作のパフォーマンスを向上させるインデックスです。クラスター化されたコレクションには、クラスター化されたインデックスのキー値順にドキュメントが格納されます。
クラスター化インデックスを作成するには、CollectionOption で clusteredIndex オプションを指定します。clusteredIndex オプションでは、キーとして _id フィールドを指定し、ユニークなフィールドを true として指定する必要があります。
次の例では、createCollection() メソッドを使用して tea データベースの vendors コレクションの _id フィールドにクラスター化インデックスが作成されています。
const db = client.db('tea'); await db.createCollection('ratings', { clusteredIndex: { key: { _id: 1 }, unique: true } });
詳しくは、「クラスター化インデックス」と「クラスター化コレクション」を参照してください。
Text Indexes
テキスト インデックスは、文字列コンテンツに対するテキスト検索クエリをサポートします。これらのインデックスには、値が文字列または複数の文字列配列である任意のフィールドを含めることができます。
MongoDB はさまざまな言語のテキスト検索をサポートしているため、インデックスを作成するときにオプションとしてデフォルトの言語を指定できます。重みオプションを指定して、インデックス内の特定のテキスト フィールドに優先順位を付けることもできます。これらの重みは、他のインデックス付きフィールドと比較したフィールドの重要性を示します。
テキスト検索について詳しくは、 テキスト検索クエリ ガイドをご覧ください。
次の例では、 createIndex()メソッドを使用して次のアクションが実行されています。
blogPostsコレクションのtitleおよびbodyフィールドにtextインデックスを作成しますデフォルト言語として
englishを指定しますbodyのフィールドの重みを10に、titleのフィールドの重みを3に設定します
// Get the database and collection on which to create the index const myDB = client.db("testDB"); const myColl = myDB.collection("blogPosts"); // Create a text index on the "title" and "body" fields const result = await myColl.createIndex( { title: "text", body: "text" }, { default_language: "english", weights: { body: 10, title: 3 } } );
次のクエリは、前のコードで作成されたテキスト インデックスを使用します。
// Query for documents where body or title contain "life ahead" const query = { $text: { $search: "life ahead" } }; // Show only the title field const projection = { _id: 0, title: 1 }; // Execute the find operation const cursor = myColl.find(query).project(projection);
テキスト インデックスの詳細については、サーバー マニュアルの「テキストインデックス 」を参照してください。
地理空間インデックス
MongoDB は、2dsphere インデックス を使用した地理空間座標データのクエリをサポートしています。2dsphere インデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。MongoDB Node.js ドライバーを使用して地理空間データをクエリする方法について詳しくは、地理空間の検索ガイドをご覧ください。
2dsphere インデックスを作成するには、GeoJSON オブジェクト のみを含むフィールドを指定する必要があります。これについて詳しくは、MongoDB Server マニュアルの「GeoJSON オブジェクト」のページを参照してください。
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 ] } } }
次の例では、createIndexes() メソッドを使用して、sample_mflix データベースの theaters コレクションの location.geo フィールドに2dsphereインデックスが作成され、地理空間検索が有効にされています。
const database = client.db("sample_mflix"); const movies = database.collection("movies"); /* Create a 2dsphere index on the "location.geo" field in the "movies" collection */ const result = await movies.createIndex({ "location.geo": "2dsphere" }); // Print the result of the index creation console.log(`Index created: ${result}`);
MongoDB は、ユークリッド平面上の距離を計算し、MongoDB 2.2以前で使用される「legacy coordinate pairs」構文を操作するための2dインデックスもサポートしています。 詳細については、「地理空間クエリ 」を参照してください。
Unique Indexes
ユニークインデックスにより、インデックス フィールドに重複する値が格納されなくなります。デフォルトでは、MongoDB はコレクションの作成時に _id フィールドにユニークインデックスを作成します。ユニークインデックスを作成するには、重複を防ぐフィールドまたはフィールドの組み合わせを指定し、unique オプションを true に設定します。
次の例では、createIndex() メソッドを使用して、sample_mflix データベースの theaters コレクションの theaterId フィールドにユニークインデックスが作成されています。
const database = client.db("sample_mflix"); const movies = database.collection("movies"); // Create a unique index on the "theaterId" field in the "theaters" collection. const result = await movies.createIndex({ theaterId: 1 }, { unique: true }); console.log(`Index created: ${result}`);
ユニークインデックスに違反する重複値を格納する書込み操作を実行しようとすると、MongoDB は次のようなエラーを返します。
E11000 duplicate key error index
詳細については、「一意のインデックス 」を参照してください。
検索インデックス
Atlas Search は、全文検索を実行できる機能です。 詳しくは、 Atlas Searchのドキュメントを参照してください。
Atlas コレクションで検索を実行する前に、まずコレクションに Atlas Search インデックスを作成する必要があります。Atlas Search インデックスは、検索可能な形式でデータを分類するデータ構造です。
検索インデックスの管理には以下の方法があります。
createSearchIndex()createSearchIndexes()listSearchIndexes()updateSearchIndex()dropSearchIndex()
次のセクションでは、前述の各方法を使用して検索インデックスを管理するコード サンプルを紹介します。
検索インデックスを作成
createSearchIndex() メソッドと createSearchIndexes() メソッドを使用して、新しい検索インデックスを作成できます。
次のコードを使用することで、createSearchIndex() メソッドで search1 というインデックスを作成する方法が表示されます。
// Create a search index const index1 = { name: "search1", definition: { "mappings": { "dynamic": true } } } await collection.createSearchIndex(index1);
MongoDB Server v 6.0.11以降の v 6バージョン、または v 7.0.2以降の v 7バージョンに接続する場合、 ドライバーを使用してコレクションに Atlas Vector Search インデックスを作成できます。 この機能の詳細については、 Atlas Vector Search のドキュメント を参照してください。
次のコードは、 createSearchIndex()メソッドを使用して、 typeフィールドがvectorSearchである検索インデックスを作成する方法を示しています。
// Create a Vector Search index const vectorSearchIdx = { name: "vsidx1", type: "vectorSearch", definition: { fields: [{ type: "vector", numDimensions: 384, path: "summary", similarity: "dotProduct" }] } } await collection.createSearchIndex(vectorSearchIdx);
検索インデックスをリストする
listSearchIndexes() メソッドを使用して、特定のコレクションの検索インデックスを含むカーソルを返すことができます。listSearchIndexes() メソッドでは、任意の string パラメータ name が使われ、名前が一致するインデックスのみが返されます。また、任意の aggregateOptions パラメーターも使われます。
次のコードを使用することで、 listSearchIndexes() メソッドで、コレクション内の検索インデックスが一覧表示されます。
// List search indexes const result = await collection.listSearchIndexes().toArray(); console.log("Existing search indexes:\n"); for (const doc in result) { console.log(doc); }
検索インデックスをアップデートする
updateSearchIndex() メソッドを使用して、検索インデックスを更新できます。
次のコードを使用することで、 updateSearchIndex() メソッドで search1 というインデックスを更新し、 description フィールドの文字列を指定する方法が表示されます。
// Update a search index const index2 = { "mappings": { "dynamic": true, "fields": { "description": { "type": "string" } } } } await collection.updateSearchIndex("search1", index2);
検索インデックスを削除する
dropSearchIndex() メソッドを使用して、検索インデックスを削除することができます。
次のコードを使用することで、 dropSearchIndex()メソッドで search1 というインデックスを削除する方法が表示されます。
// Dropping (deleting) a search index await collection.dropSearchIndex("search1");