Když v MongoDB vytvoříte index zástupných znaků, máte možnost zadat jedno pole, všechna pole nebo jen některá.
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 zahrnutí konkrétních polí do 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, ale zahrnout pouze pole, která chceme.
Vytvořte index
Zde je příklad:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.type" : 1,
"details.born" : 1
}
}
)
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í zahrnout. V tomto případě jsme zahrnuli details.type
pole a details.born
pole. Přiřadíte jim hodnotu 1
explicitně je zahrne do indexu.
Zobrazit rejstřík
Indexy v kolekci můžeme zobrazit 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.type" : 1, "details.born" : 1 } } ]
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.
Otestujte index
Můžeme také spustit nějaké dotazy, abychom zjistili, zda bude náš index použit nebo ne.
Teoreticky by následující dotaz měl používat index:
db.pets.find( { "details.type" : "Dog" } )
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 pole, které není zahrnuto v indexu:
db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()
Výsledek:
{ "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 }
V tomto případě provedl skenování kolekce (COLLSCAN), takže podle očekávání nepoužil index.