Docs Menu
Docs Home
/
MongoDBマニュアル
/ /

Sparse Indexes

項目一覧

  • スパース インデックスの作成
  • 動作

スパース インデックスには、インデックス フィールドに null 値が含まれていても、インデックスフィールドを持つドキュメントのエントリのみが含まれます。インデックスは、インデックス付きフィールドが欠落しているドキュメントをスキップします。コレクションのすべてのドキュメントが含まれているわけではないため、インデックスは "スパース" です。一方、非スパース インデックスにはコレクション内のすべてのドキュメントが含まれ、インデックス フィールドを含まないドキュメントには null 値がストアされます。

重要

MongoDB には、 部分インデックスを作成するオプションが用意されています。 部分インデックスは 、スパースインデックスの機能のスーパーセットを提供します。 部分インデックスは、スパースインデックスよりも優先され、

スパース インデックスを作成するには、sparse オプションを true に設定した db.collection.createIndex() メソッドを使用します。

たとえば、 mongoshの次の操作では、addresses コレクションの xmpp_id フィールドにsparse indexが作成されます。

db.addresses.createIndex( { "xmpp_id": 1 }, { sparse: true } )

インデックスは、xmpp_id フィールドを含まないドキュメントをインデックスしません。

注意

MongoDB のスパース インデックスと、他のデータベースのブロックレベル インデックスを混同しないでください。特定のフィルターを備えた密なインデックスと考えてください。

スパース インデックスによって、クエリやソート操作の結果セットが不完全になる場合、hint() で明示的にインデックスを指定しない限り、MongoDB はそのインデックスを使用しません。

たとえば、クエリ { x: { $exists: false } } では、明示的なヒントがない限り x フィールドにスパース インデックスを使用しません。動作の詳細を示す例については、「コレクションのスパース インデックスが完全な結果を返さない」を参照してください。

コレクション内のすべてのドキュメントの count() を実行するときに、スパース インデックスを指定する hint() を含めると(つまり、クエリ述語が空の場合)、スパース インデックスの結果が不正確なカウントになった場合でも、スパース インデックスが使用されます。

db.collection.insertOne( { _id: 1, y: 1 } );
db.collection.createIndex( { x: 1 }, { sparse: true } );
db.collection.find().hint( { x: 1 } ).count();

正しいカウントを取得するには、コレクション内のすべてのドキュメントのカウントを実行するときに、スパース インデックスを使用して hint() を実行しないでください。

db.collection.find().count();
db.collection.createIndex( { y: 1 } );
db.collection.find().hint( { y: 1 } ).count();

次のインデックスの種類は、常にスパースです。

複合インデックスには、さまざまなタイプのスパースインデックスを含めることができます。インデックスのタイプの組み合わせによって、複合インデックスがドキュメントと一致する方法が決まります。

下表には、さまざまなタイプのスパースインデックスを含む複合インデックスの動作がまとめられています。

複合インデックスの構成要素
複合インデックスの動作
Ascending indexes
Descending indexes
1 つ以上のキーの値を含むドキュメントのみ、インデックスが作成されます。
Ascending indexes
Descending indexes
geospatial フィールドのいずれかに値が含まれている場合にのみ、ドキュメントのインデックスが作成されます。昇順または降順インデックス形式のドキュメントのインデックスは作成されません。
Ascending indexes
Descending indexes
text フィールドのいずれかに一致するドキュメントのみ、インデックスが作成されます。昇順または降順インデックス形式のドキュメントのインデックスは作成されません。

インデックスがスパースかつ一意の場合、フィールドの値が重複するドキュメントがコレクションに含まれることはありませんが、キーが省略された複数のドキュメントは許可されます。

以下のドキュメントを含むコレクション scores を考慮します:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

コレクションにはフィールド score のスパース インデックスがあります:

db.scores.createIndex( { score: 1 } , { sparse: true } )

次に、scores コレクションに対する次のクエリは、スパース インデックスを使用して、score フィールドが($lt90 より小さいドキュメントを返します。

db.scores.find( { score: { $lt: 90 } } )

ユーザー ID "newbie" のドキュメントには score フィールドが含まれていないためにクエリ条件を満たさないことから、クエリではスパース インデックスを使用して結果を返すことができます。

{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

以下のドキュメントを含むコレクション scores を考慮します:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

コレクションにはフィールド score のスパース インデックスがあります:

db.scores.createIndex( { score: 1 } , { sparse: true } )

ユーザー ID "newbie" のドキュメントには score フィールドが含まれていないため、スパース インデックスにはそのドキュメントのエントリは含まれません。

scores コレクションのすべてのドキュメントを score フィールドでソートして返すには、次のクエリを考慮します:

db.scores.find().sort( { score: -1 } )

インデックス付きフィールドでソートしても、MongoDB は、完全な結果を返すことを目的としてクエリを満たすために、スパース インデックスを選択することはありません

{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }

スパース インデックスを使用するには、hint() を使用してインデックスを明示的に指定します。

db.scores.find().sort( { score: -1 } ).hint( { score: 1 } )

インデックスを使用すると、score フィールドを持つドキュメントのみが返されます。

{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }

Tip

以下も参照してください。

以下のドキュメントを含むコレクション scores を考慮します:

{ "_id" : ObjectId("523b6e32fb408eea0eec2647"), "userid" : "newbie" }
{ "_id" : ObjectId("523b6e61fb408eea0eec2648"), "userid" : "abby", "score" : 82 }
{ "_id" : ObjectId("523b6e6ffb408eea0eec2649"), "userid" : "nina", "score" : 90 }

次の操作を使用して、score フィールドにユニーク制約とスパースフィルターを持つインデックスを作成できます。

db.scores.createIndex( { score: 1 } , { sparse: true, unique: true } )

このインデックスにより、score フィールドにユニークな値を持つドキュメント、あるいは score フィールドが含まれていないドキュメントの挿入が許可されます。そのため、scores コレクション内の既存のドキュメントを前提として、インデックスでは以下の挿入操作が可能です。

db.scores.insertMany( [
{ "userid": "newbie", "score": 43 },
{ "userid": "abby", "score": 34 },
{ "userid": "nina" }
] )

ただし、score 値が 8290 のドキュメントがすでに存在するため、インデックスでは次のドキュメントの追加が許可されません

db.scores.insertMany( [
{ "userid": "newbie", "score": 82 },
{ "userid": "abby", "score": 90 }
] )

MongoDB5.0 以降、 キー パターン が同じ 一意のスパース および 一意の非スパース インデックスを単一コレクションに混在させることができます。

次の例では、キー パターンが同じで sparse オプションが異なる複数のインデックスを作成します。

db.scoreHistory.createIndex( { score : 1 }, { name: "unique_index", unique: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "unique_sparse_index", unique: true, sparse: true } )

スパース オプションの有無にかかわらず、同じキー パターンで基本インデックスを作成することもできます。

db.scoreHistory.createIndex( { score : 1 }, { name: "sparse_index", sparse: true } )
db.scoreHistory.createIndex( { score : 1 }, { name: "basic_index" } )

戻る

Hidden Indexes