MongoDBでワイルドカードインデックスを作成する場合、単一のフィールド、すべてのフィールド、または一部のみを指定するオプションがあります。
特定のフィールドを除外するオプションもあります。つまり、を除くすべてのフィールドを指定できます。 1つ以上の特定のフィールド用。
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.awards" : 0,
"details.eats" : 0
}
}
) 出力:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
{ "$**" : 1 } 一部はワイルドカードインデックスを作成するものであり、wildcardProjection partは、除外するフィールドを指定する部分です。この場合、details.awardsを除外しました フィールドとdetails.eats 分野。それらに0の値を与える それらをインデックスから明示的に除外します。
インデックスを表示
getIndexes()を呼び出すと、コレクションのインデックスを確認できます。 方法:
db.pets.getIndexes() 結果:
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_"
},
{
"v" : 2,
"key" : {
"$**" : 1
},
"name" : "$**_1",
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
] 2つのインデックスがあることがわかります。
- 最初のインデックスは
_idにあります 分野。これは、コレクションが作成されたときに作成されました(MongoDBは、コレクションの作成中に_idフィールドに一意のインデックスを作成します)。 - 2番目のインデックスはワイルドカードインデックスです。自動的に
$**_1という名前が付けられていることがわかります 、および0の値とともに指定したフィールドが含まれます 、これは、それらがインデックスから明示的に除外されていることを意味します。
インデックスをテストする
いくつかのクエリを実行して、インデックスが使用されるかどうか、および除外されたフィールドが実際に除外されるかどうかを確認することもできます
次のクエリではインデックスを使用する必要があります:
db.pets.find( { "details.type" : "Dog" } )
details.typeを除外しなかったため、インデックスを使用する必要があります インデックスからのフィールド。
これをテストするために、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)を使用したことがわかります。
これとは対照的に、除外したフィールドの1つでクエリを実行すると、次のようになります。 インデックスから:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain() 結果:
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "PetHotel.pets",
"indexFilterSet" : false,
"parsedQuery" : {
"details.awards.Florida Dog Awards" : {
"$eq" : "Top Dog"
}
},
"queryHash" : "16FBC17B",
"planCacheKey" : "16FBC17B",
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"details.awards.Florida Dog Awards" : {
"$eq" : "Top Dog"
}
},
"direction" : "forward"
},
"rejectedPlans" : [ ]
},
"ok" : 1
} この場合、コレクションスキャン(COLLSCAN)を実行したため、予想どおり、インデックスは使用されませんでした。