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)を実行したため、予想どおり、インデックスは使用されませんでした。