MongoDBでワイルドカードインデックスを作成する場合、単一のフィールド、すべてのフィールド、または一部のみを指定するオプションがあります。
wildcardProjection
を使用できます ワイルドカードインデックスから特定のフィールドパスを含めるか除外するパラメータ。この記事では、ワイルドカードインデックスに特定のフィールドを含める例を示します。
サンプルドキュメント
pets
というコレクションがあるとします。 次のドキュメントを使用:
{ "_id" : 1, "name" : "Wag", "details" : { "type" : "Dog", "weight" : 20, "awards" : { "Florida Dog Awards" : "Top Dog", "New York Marathon" : "Fastest Dog", "Sumo 2020" : "Biggest Dog" } } } { "_id" : 2, "name" : "Fetch", "details" : { "born" : ISODate("2020-06-22T14:00:00Z"), "color" : "Black" } } { "_id" : 3, "name" : "Scratch", "details" : { "eats" : [ "Mouse Porridge", "Bird Soup", "Caviar" ], "type" : "Cat", "born" : ISODate("2020-12-19T14:00:00Z") } }
コレクション全体にワイルドカードインデックスを作成できますが、必要なフィールドのみを含めます。
インデックスを作成する
次に例を示します:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.type" : 1,
"details.born" : 1
}
}
)
出力:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
一部はワイルドカードインデックスを作成するものであり、wildcardProjection
partは、含めるフィールドを指定する部分です。この場合、details.type
を含めました フィールドとdetails.born
分野。それらに1
の値を与える それらを明示的にインデックスに含めます。
インデックスを表示
getIndexes()
を呼び出すことで、コレクションのインデックスを表示できます。 方法:
db.pets.getIndexes()
結果:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.type" : 1, "details.born" : 1 } } ]
2つのインデックスがあることがわかります。
- 最初のインデックスは
_id
にあります 分野。これは、コレクションが作成されたときに作成されました(MongoDBは、コレクションの作成中に_idフィールドに一意のインデックスを作成します)。 - 2番目のインデックスはワイルドカードインデックスです。自動的に
$**_1
という名前が付けられていることがわかります 、および指定したフィールドが含まれます。
インデックスをテストする
いくつかのクエリを実行して、インデックスが使用されるかどうかを確認することもできます。
理論的には、次のクエリではインデックスを使用する必要があります。
db.pets.find( { "details.type" : "Dog" } )
これをテストするために、explain()
を追加できます クエリプランを表示する方法:
db.pets.find( { "details.type" : "Dog" } ).explain()
結果:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHotel.pets", "indexFilterSet" : false, "parsedQuery" : { "details.type" : { "$eq" : "Dog" } }, "queryHash" : "F1C5286F", "planCacheKey" : "5326DE93", "winningPlan" : { "stage" : "FETCH", "inputStage" : { "stage" : "IXSCAN", "keyPattern" : { "$_path" : 1, "details.type" : 1 }, "indexName" : "$**_1", "isMultiKey" : false, "multiKeyPaths" : { "$_path" : [ ], "details.type" : [ ] }, "isUnique" : false, "isSparse" : false, "isPartial" : false, "indexVersion" : 2, "direction" : "forward", "indexBounds" : { "$_path" : [ "[\"details.type\", \"details.type\"]" ], "details.type" : [ "[\"Dog\", \"Dog\"]" ] } } }, "rejectedPlans" : [ ] }, "ok" : 1 }
インデックスでインデックススキャン(IXSCAN)を使用したことがわかります。
これとは対照的に、ではないフィールドでクエリを実行すると次のようになります。 インデックスに含まれる:
db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()
結果:
{ "queryPlanner" : { "plannerVersion" : 1, "namespace" : "PetHotel.pets", "indexFilterSet" : false, "parsedQuery" : { "details.awards.New York Marathon" : { "$eq" : "Fastest Dog" } }, "queryHash" : "EC0D5185", "planCacheKey" : "EC0D5185", "winningPlan" : { "stage" : "COLLSCAN", "filter" : { "details.awards.New York Marathon" : { "$eq" : "Fastest Dog" } }, "direction" : "forward" }, "rejectedPlans" : [ ] }, "ok" : 1 }
この場合、コレクションスキャン(COLLSCAN)を実行したため、予想どおり、インデックスは使用されませんでした。