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
_idpole. 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
$**_1a 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.