Docs Menu
Docs Home
/ / /
Java 同期
/

Indexes

項目一覧

  • Overview
  • クエリ範囲とパフォーマンス
  • 操作上の考慮事項
  • インデックス タイプ
  • 単一フィールドと複合インデックス
  • マルチキー インデックス(配列フィールドへのインデックス)
  • Text Indexes
  • 地理空間インデックス
  • Unique Indexes
  • ワイルドカード インデックス
  • クラスター化インデックス
  • インデックスを削除する
  • インデックス仕様ドキュメントを使用したインデックスの削除
  • 名前フィールドを使用したインデックスの削除
  • ワイルドカード文字を使用したインデックスの削除

このガイドでは、MongoDB Java ドライバーでインデックスを使用する方法を学習できます。

インデックスは、MongoDB でクエリを効率的に実行するのに役立ちます。 インデックスがないと、MongoDB はコレクション内のすべてのドキュメントをスキャンする必要があります(コレクションスキャン)。 これらのコレクションスキャンは遅く、アプリケーションのパフォーマンスに悪影響を与える可能性があります。 クエリに適切なインデックスがある場合、MongoDB ではそのインデックスを使用して検査する必要があるドキュメントの数を制限できます。

インデックスも:

  • 効率的なソートを許可する

  • 地理空間検索などの特殊機能を有効にする

  • フィールド値を一意のものにするために制約を追加できるようにする

  • 以上

Tip

インデックスは、アップデートするドキュメントを見つけるときはアップデート操作、削除するドキュメントを見つけた場合は削除操作、および 集計パイプライン の特定のステージでも使用されます。

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

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

  • クエリの実行に影響するオプション(例: 読み取り保証 (read concern))

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

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

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

重要

並び替え順

ソート条件は、インデックスの順序と一致するか、その順序を逆にする必要があります。

name昇順(AZ)でフィールドage と降順(9-0)のフィールド のインデックスを検討します。

name_1_age_-1

MongoDB は、次のいずれかでデータをソートするときにこのインデックスを使用します。

  • name 昇順、 age降順

  • name 降順、 ageの昇順

name ageの昇順、またはnameageの降順の並べ替え順序を指定するには、メモリ内でソートする必要があります。

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

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

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

データモデルの設計とアプリケーションに適したインデックスの選択の詳細については、「 MongoDB Server のデータ モデリングとインデックス 」を参照してください。

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

Tip

MongoDB Java ドライバーは インデックス を提供します さまざまな MongoDB インデックス キー タイプのインデックス仕様ドキュメントを作成するための静的ファクトリー メソッドを含むクラス。

次の例では createIndex() メソッド を メソッドを使用してさまざまなインデックスを作成し、次の設定を行います。

import com.mongodb.DuplicateKeyException;
import com.mongodb.MongoCommandException;
import com.mongodb.client.*;
import com.mongodb.client.model.IndexOptions;
import com.mongodb.client.model.Indexes;
import com.mongodb.client.model.Sorts;
import com.mongodb.client.model.geojson.Point;
import com.mongodb.client.model.geojson.Position;
import org.apache.log4j.BasicConfigurator;
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;
final String uri = "mongodb+srv://<atlas-uri>/<dbname>?retryWrites=true&w=majority";
mongoClient = MongoClients.create(uri);
database = mongoClient.getDatabase("sample_mflix");
collection = database.getCollection("movies");

単一フィールド インデックスは、コレクションのドキュメント内の単一のフィールドを参照するインデックスです。 単一フィールド クエリとソートのパフォーマンスが向上し、一定時間の経過後または特定のクロック時間にコレクションからドキュメントを自動的に排除するTTL インデックスをサポートします。

注意

_id_インデックスは、単一フィールド インデックスの例です。 このインデックスは、新しいコレクションが作成されるときに、 _idフィールドに自動的に作成されます。

次の例では、 titleフィールドに昇順のインデックスを作成します。

String resultCreateIndex = collection.createIndex(Indexes.ascending("title"));
System.out.println(String.format("Index created: %s", resultCreateIndex));

以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。

Bson filter = eq("title", "Batman");
Bson sort = Sorts.ascending("title");
Bson projection = fields(include("title"), excludeId());
FindIterable<Document> cursor = collection.find(filter).sort(sort).projection(projection);

詳細については、MongoDB Server マニュアルの「 単一フィールド インデックス 」を参照してください。

複合インデックス は、コレクションのドキュメント内の複数のフィールドへの参照を保持し、クエリとソートのパフォーマンスを向上させます。

Tip

複合インデックス、インデックス プレフィックス、ソート順序の詳細については、こちらをご覧ください。

次の例では、 フィールドと フィールドに複合インデックスを作成しています。typerated

String resultCreateIndex = collection.createIndex(Indexes.ascending("type", "rated"));
System.out.println(String.format("Index created: %s", resultCreateIndex));

以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。

Bson filter = and(eq("type", "movie"), eq("rated", "G"));
Bson sort = Sorts.ascending("type", "rated");
Bson projection = fields(include("type", "rated"), excludeId());
FindIterable<Document> cursor = collection.find(filter).sort(sort).projection(projection);

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

マルチキー インデックスは、配列値を含むインデックスを持つフィールドを指定するクエリのパフォーマンスを向上させるインデックスです。 単一フィールドまたは複合インデックスと同じ構文を使用してマルチキー インデックスを定義できます。

次の例では、 ratedgenres (文字列の配列)、 titleフィールドに複合マルチキー インデックスを作成します。

String resultCreateIndex = collection.createIndex(Indexes.ascending("rated", "genres", "title"));
System.out.println(String.format("Index created: %s", resultCreateIndex));

以下は、前のコード スニペットで作成されたインデックスによってカバーされるクエリの例です。

Bson filter = and(eq("genres", "Animation"), eq("rated", "G"));
Bson sort = Sorts.ascending("title");
Bson projection = fields(include("title", "rated"), excludeId());
FindIterable<Document> cursor = collection.find(filter).sort(sort).projection(projection);

マルチキー インデックスは、クエリ カバレッジ、インデックスバウンド計算、およびソート動作の点で他のインデックスとは動作が異なります。 マルチキー インデックス(動作や制限事項を含む)について詳しくは、MongoDB マニュアルの「 マルチキー インデックス 」のページを参照してください。

テキスト インデックスは、string コンテンツに対するテキスト検索クエリをサポートします。 これらのインデックスには、値が string または複数の string 配列である任意のフィールドを含めることができます。 MongoDB はさまざまな言語のテキスト検索をサポートしています。 インデックスの作成時に、オプションとしてデフォルト言語を指定できます。

Tip

テキスト インデックスは、より強力なAtlas Full Text Searchインデックスとは異なります。 Atlas ユーザーは Atlas Search を使用する必要があります。

次の例では、 plotフィールドに テキスト インデックスを作成しています。

try {
String resultCreateIndex = collection.createIndex(Indexes.text("plot"));
System.out.println(String.format("Index created: %s", resultCreateIndex));
// Prints a message if a text index already exists with a different configuration
} catch (MongoCommandException e) {
if (e.getErrorCodeName().equals("IndexOptionsConflict"))
System.out.println("there's an existing text index with different options");
}

以下は、前のコード スニペットで作成されたインデックスを使用するクエリの例です。 テキスト インデックスにはソート順序が含まれていないため、 sortは省略されていることに注意してください。

Bson filter = text("java coffee shop");
Bson projection = fields(include("fullplot"), excludeId());
FindIterable<Document> cursor = collection.find(filter).projection(projection);

コレクションには 1 つのテキスト インデックスしか含めることができません。 複数のテキストフィールドのテキストインデックスを作成する場合は、複合インデックスを作成する必要があります。 複合インデックス内のすべてのテキスト フィールドに対してテキスト検索が実行されます。

次のスニペットは、 フィールドと フィールドの複合テキストtitle genreインデックスを作成します。

collection.createIndex(Indexes.compoundIndex(Indexes.text("title"), Indexes.text("genre")));

詳細については、次のサーバー マニュアル エントリを参照してください。

MongoDB は、 2 dsphere インデックスを使用した地理空間座標データのクエリをサポートしています。 2dsphereインデックスを使用すると、包含、交差、近接性について地理空間データを照会できます。 地理空間データのクエリの詳細については、「地理空間クエリ 」を参照してください。

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
]
}
}
}

次の例では、 location.geoフィールドに2dsphereインデックスを作成します。

重要

地理空間インデックスによってカバーされているフィールドに地理空間インデックスを作成しようとすると、エラーが発生します。

try {
String resultCreateIndex = collection.createIndex(Indexes.geo2dsphere("location.geo"));
System.out.println(String.format("Index created: %s", resultCreateIndex));
// Prints a message if a geospatial index already exists with a different configuration
} catch (MongoCommandException e) {
if (e.getErrorCodeName().equals("IndexOptionsConflict"))
System.out.println("there's an existing geospatial index with different options");
}

以下は、「location.geo」を使用した地理空間クエリの例です。 インデックス。

// Stores the coordinates of the NY MongoDB headquarters
Point refPoint = new Point(new Position(-73.98456, 40.7612));
// Retrieves documents that represent locations up to 1000 meters from the specified point directly from the geospatial index
// Creates a filter to match a document
Bson filter = near("location.geo", refPoint, 1000.0, 0.0);
FindIterable<Document> cursor = collection.find(filter);

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

ユニークインデックスにより、インデックス フィールドに重複する値が格納されなくなります。デフォルトでは、MongoDB はコレクションの作成時に _id フィールドにユニークインデックスを作成します。ユニークインデックスを作成するには、重複を防ぐフィールドまたはフィールドの組み合わせを指定し、unique オプションを true に設定します。

次の例では、 theaterIdフィールドに一意の降順インデックスを作成しています。

try {
IndexOptions indexOptions = new IndexOptions().unique(true);
String resultCreateIndex = collection.createIndex(Indexes.descending("theaterId"), indexOptions);
System.out.println(String.format("Index created: %s", resultCreateIndex));
// Prints a message if the "theaterID" field contains duplicate values
} catch (DuplicateKeyException e) {
System.out.printf("duplicate field values encountered, couldn't create index: \t%s\n", e);
}

重要

一意なインデックスに違反する重複値を保存する書込み操作を実行すると、MongoDB Java ドライバーはDuplicateKeyExceptionを発生させ、MongoDB は次のようなエラーを返します。

E11000 duplicate key error index

詳細については、MongoDB Server マニュアルの 「 一意なインデックス 」 ページを参照してください。

ワイルドカード インデックスを使用すると、不明なフィールドや任意のフィールドに対するクエリが可能になります。 動的スキーマを使用している場合は、これらのインデックスが役立ちます。

次の例では、サブドキュメントや配列にネストされた値を含む、 locationフィールドのすべての値に対して昇順のワイルドカード インデックスを作成します。

String resultCreateIndex = collection.createIndex(Indexes.ascending("location.$**"));
System.out.println(String.format("Index created: %s", resultCreateIndex));

詳細については、MongoDB Server マニュアルの「 ワイルドカード インデックス 」のページを参照してください。

クラスター化されたインデックスは、キー値の順にドキュメントを保存するようにコレクションに指示します。 クラスター化インデックスを作成するには、コレクションを作成するときに、 _idフィールドをキーとして指定し、一意のフィールドをtrueとして指定して、 クラスター化インデックス オプション を指定します。

次の例では、 vendorsコレクションの_idフィールドにクラスター化インデックスを作成しています。

MongoDatabase database = mongoClient.getDatabase("tea");
ClusteredIndexOptions clusteredIndexOptions = new ClusteredIndexOptions(new Document("_id", 1), true);
CreateCollectionOptions createCollectionOptions = new CreateCollectionOptions().clusteredIndexOptions(clusteredIndexOptions);
database.createCollection("vendors", createCollectionOptions);

詳細については、MongoDB Server マニュアルの各セクションを参照してください。

_idフィールドのデフォルトの一意なインデックスを除く未使用のインデックスを削除できます。

次のセクションでは、インデックスを削除する方法を示します。

  • インデックス仕様ドキュメントの使用

  • インデックス付き名前フィールドの使用

  • ワイルドカード文字を使用してすべてのインデックスを削除する

インデックス仕様ドキュメントdropIndex()メソッドに渡して、コレクションからインデックスを削除します。 インデックス仕様ドキュメントは、指定されたフィールドのインデックスのタイプを指定するBsonインスタンスです。

次のスニペットは、 コレクションのtitleフィールドの昇順のインデックスを削除します。

collection.dropIndex(Indexes.ascending("title"));

重要

テキスト インデックスを削除する場合は、代わりにインデックスの名前を使用する必要があります。 詳細については、「 名前フィールドを使用したインデックスの削除 」セクションを参照してください。

コレクションからインデックスを削除するには、インデックスのnameフィールドをdropIndex()メソッドに渡します。

インデックスの名前を検索する必要がある場合は、 listIndexes()メソッドを使用して、インデックス内のnameフィールドの値を確認します。

次のスニペットは、コレクション内のすべてのインデックスを検索して出力します。

collection.listIndexes().forEach(doc -> System.out.println(doc.toJson()));

テキスト インデックスを含むコレクションでlistIndex()を呼び出すと、出力は次のようになります。

{ "v": 2, "key": {"_id": 1}, "name": "_id_" }
{ "v": 2, "key": {"_fts": "text", "_ftsx": 1}, "name": "title_text", "weights": {"title": 1},
"default_language": "english", "language_override": "language", "textIndexVersion": 3 }

この出力では、既存のインデックスの名前が "_id" と "title_text" であることがわかります。

次のスニペットは、 コレクションから "title_text" インデックスを削除します。

collection.dropIndex("title_text");

注意

複合テキスト インデックスから単一のフィールドを削除することはできません。 インデックス フィールドを更新するには、インデックス全体を削除し、新しいインデックスを作成する必要があります。

MongoDB 4.2 以降では、コレクションでdropIndexes()メソッドを呼び出すことで、すべてのインデックスを削除できます。

collection.dropIndexes();

以前のバージョンの MongoDB の場合は、コレクションのdropIndex()への呼び出しに「*」をパラメータとして渡します。

collection.dropIndex("*");

このセクションのメソッドの詳細については、次の API ドキュメントを参照してください。

戻る

集計式演算子