Když vytvoříte index zástupných znaků v MongoDB, máte možnost zadat jedno pole, všechna pole nebo jen některá.
Máte také možnost vyloučit některá pole. Jinými slovy, můžete zadat všechna pole kromě pro jedno nebo více konkrétních polí.
Můžete použít wildcardProjection
parametr pro zahrnutí nebo vyloučení konkrétních cest polí z indexu zástupných znaků. Tento článek představuje příklad vyloučení konkrétních polí v indexu zástupných znaků.
Ukázkový dokument
Předpokládejme, že máme sbírku nazvanou pets
s následujícími dokumenty:
{ "_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") } }
Mohli bychom vytvořit zástupný index pro celou kolekci, přičemž bychom vyloučili určitá pole.
Vytvořte index
Zde je příklad:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Výstup:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
část je to, co vytváří index zástupných znaků a wildcardProjection
část je část, která určuje, která pole se mají vyloučit. V tomto případě jsme vyloučili details.awards
pole a details.eats
pole. Přiřadíte jim hodnotu 0
explicitně je vyloučí z indexu.
Zobrazit rejstřík
Indexy v kolekci můžeme vidět voláním getIndexes()
metoda:
db.pets.getIndexes()
Výsledek:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Vidíme, že existují dva indexy.
- První index je na
_id
pole. Toto bylo vytvořeno při vytváření kolekce (MongoDB vytvoří jedinečný index v poli _id během vytváření kolekce). - Druhý index je náš zástupný index. Vidíme, že byl automaticky pojmenován
$**_1
a zahrnuje pole, která jsme zadali spolu s hodnotou0
, což znamená, že jsou z indexu výslovně vyloučeny.
Otestujte index
Můžeme také spustit nějaké dotazy, abychom zjistili, zda bude náš index použit a zda vyloučená pole budou skutečně vyloučena
Následující dotaz by měl používat index:
db.pets.find( { "details.type" : "Dog" } )
Měl by používat index, protože jsme nevyloučili details.type
pole z indexu.
Abychom to otestovali, můžeme připojit explain()
způsob zobrazení plánu dotazů:
db.pets.find( { "details.type" : "Dog" } ).explain()
Výsledek:
{ "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 }
Vidíme, že použil indexové skenování (IXSCAN) na našem indexu.
Na rozdíl od toho zde je to, co se stane, když spustíme dotaz na jedno z polí, které jsme vyloučili z indexu:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Výsledek:
{ "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 }
V tomto případě provedl skenování kolekce (COLLSCAN), takže podle očekávání nepoužil index.