Podczas tworzenia indeksu wieloznacznego w MongoDB masz możliwość określenia pojedynczego pola, wszystkich pól lub tylko niektórych.
Masz również możliwość wykluczenia niektórych pól. Innymi słowy, możesz określić wszystkie pola z wyjątkiem dla jednego lub więcej określonych pól.
Możesz użyć wildcardProjection
parametr, aby uwzględnić lub wykluczyć określone ścieżki pól z indeksu symboli wieloznacznych. W tym artykule przedstawiono przykład wykluczenia określonych pól w indeksie symboli wieloznacznych.
Przykładowy dokument
Załóżmy, że mamy kolekcję o nazwie pets
z następującymi dokumentami:
{ "_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") } }
Moglibyśmy utworzyć indeks wieloznaczny dla całej kolekcji, wyłączając niektóre pola.
Utwórz indeks
Oto przykład:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Wyjście:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
część tworzy indeks wieloznaczny, a wildcardProjection
część to część określająca, które pola mają zostać wykluczone. W tym przypadku wykluczyliśmy details.awards
pole i details.eats
pole. Nadanie im wartości 0
wyraźnie wyklucza je z indeksu.
Wyświetl indeks
Możemy zobaczyć indeksy w kolekcji, wywołując getIndexes()
metoda:
db.pets.getIndexes()
Wynik:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Widzimy, że istnieją dwa indeksy.
- Pierwszy indeks znajduje się w
_id
pole. Zostało to utworzone podczas tworzenia kolekcji (MongoDB tworzy unikalny indeks w polu _id podczas tworzenia kolekcji). - Drugi indeks to nasz indeks wieloznaczny. Widzimy, że został automatycznie nazwany
$**_1
i zawiera pola, które określiliśmy wraz z wartością0
, co oznacza, że są wyraźnie wykluczone z indeksu.
Przetestuj indeks
Możemy również uruchomić kilka zapytań, aby sprawdzić, czy nasz indeks będzie używany i czy rzeczywiście wykluczone pola zostaną wykluczone
Następujące zapytanie powinno używać indeksu:
db.pets.find( { "details.type" : "Dog" } )
Powinien używać indeksu, ponieważ nie wykluczyliśmy details.type
pole z indeksu.
Aby to przetestować, możemy dołączyć explain()
metoda przeglądania planu zapytań:
db.pets.find( { "details.type" : "Dog" } ).explain()
Wynik:
{ "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 }
Widzimy, że użył skanowania indeksu (IXSCAN) w naszym indeksie.
W przeciwieństwie do tego, oto co się dzieje, gdy uruchamiamy zapytanie w jednym z pól, które wykluczyliśmy z indeksu:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Wynik:
{ "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 }
W tym przypadku wykonał skanowanie kolekcji (COLLSCAN), więc zgodnie z oczekiwaniami nie użył indeksu.