Wanneer u een wildcard-index in MongoDB maakt, heeft u de mogelijkheid om een enkel veld, alle velden of slechts enkele op te geven.
U heeft ook de mogelijkheid om bepaalde velden uit te sluiten. Met andere woorden, u kunt alle velden specificeren behalve voor een of meer specifieke velden.
U kunt de wildcardProjection
. gebruiken parameter om specifieke veldpaden op te nemen of uit te sluiten van de wildcardindex. Dit artikel geeft een voorbeeld van het uitsluiten van specifieke velden in de wildcard-index.
Voorbeelddocument
Stel dat we een verzameling hebben met de naam pets
met de volgende documenten:
{ "_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") } }
We zouden een wildcard-index kunnen maken voor de hele collectie, terwijl we bepaalde velden uitsluiten.
De index maken
Hier is een voorbeeld:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Uitgang:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
De { "$**" : 1 }
een deel is wat de wildcard-index maakt, en de wildcardProjection
deel is het deel dat aangeeft welke velden moeten worden uitgesloten. In dit geval hebben we de details.awards
uitgesloten veld en de details.eats
veld. Geef ze een waarde van 0
sluit ze expliciet uit van de index.
Bekijk de index
We kunnen de indexen van de collectie zien door de getIndexes()
. aan te roepen methode:
db.pets.getIndexes()
Resultaat:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
We kunnen zien dat er twee indexen zijn.
- De eerste index staat op de
_id
veld. Dit is gemaakt toen de verzameling werd gemaakt (MongoDB creëert een unieke index op het _id-veld tijdens het maken van een verzameling). - De tweede index is onze wildcard-index. We kunnen zien dat het automatisch de naam
$**_1
heeft gekregen , en het bevat de velden die we hebben gespecificeerd samen met een waarde van0
, wat betekent dat ze expliciet zijn uitgesloten van de index.
Test de index
We kunnen ook enkele zoekopdrachten uitvoeren om te zien of onze index zal worden gebruikt en of de uitgesloten velden echt worden uitgesloten
De volgende query moet de index gebruiken:
db.pets.find( { "details.type" : "Dog" } )
Het zou de index moeten gebruiken omdat we de details.type
niet hebben uitgesloten veld uit de index.
Om dit te testen, kunnen we de explain()
. toevoegen methode om het zoekplan te bekijken:
db.pets.find( { "details.type" : "Dog" } ).explain()
Resultaat:
{ "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 }
We kunnen zien dat het een indexscan (IXSCAN) op onze index heeft gebruikt.
In tegenstelling hiermee, is dit wat er gebeurt als we een query uitvoeren op een van de velden die we uitgesloten uit de index:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Resultaat:
{ "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 }
In dit geval deed het een collectiescan (COLLSCAN), dus zoals verwacht gebruikte het de index niet.