När du skapar ett jokertecken i MongoDB har du möjlighet att ange ett enda fält, alla fält eller bara några.
Du har även möjlighet att utesluta vissa fält. Med andra ord kan du ange alla fält utom för ett eller flera specifika fält.
Du kan använda wildcardProjection
parameter för att inkludera eller exkludera specifika fältsökvägar från jokerteckenindexet. Den här artikeln presenterar ett exempel på att exkludera specifika fält i jokerteckenindexet.
Exempeldokument
Anta att vi har en samling som heter pets
med följande dokument:
{ "_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") } }
Vi skulle kunna skapa ett jokertecken för hela samlingen, samtidigt som vi utesluter vissa fält.
Skapa indexet
Här är ett exempel:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Utdata:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
del är det som skapar jokerteckenindexet och wildcardProjection
del är den del som anger vilka fält som ska exkluderas. I det här fallet har vi uteslutit details.awards
och details.eats
fält. Ge dem värdet 0
exkluderar dem uttryckligen från indexet.
Visa indexet
Vi kan se indexen på samlingen genom att anropa getIndexes()
metod:
db.pets.getIndexes()
Resultat:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Vi kan se att det finns två index.
- Det första indexet finns på
_id
fält. Detta skapades när samlingen skapades (MongoDB skapar ett unikt index på _id-fältet under skapandet av en samling). - Det andra indexet är vårt jokertecken. Vi kan se att den automatiskt har fått namnet
$**_1
, och det inkluderar fälten som vi angav tillsammans med värdet0
, vilket betyder att de uttryckligen är exkluderade från indexet.
Testa indexet
Vi kan också köra några frågor för att se om vårt index kommer att användas och om de uteslutna fälten verkligen kommer att uteslutas
Följande fråga ska använda indexet:
db.pets.find( { "details.type" : "Dog" } )
Den bör använda indexet eftersom vi inte exkluderade details.type
fält från indexet.
För att testa detta kan vi lägga till explain()
metod för att visa frågeplanen:
db.pets.find( { "details.type" : "Dog" } ).explain()
Resultat:
{ "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 }
Vi kan se att den använde en indexskanning (IXSCAN) på vårt index.
I motsats till detta, här är vad som händer när vi kör en fråga på ett av fälten som vi uteslutit från indexet:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Resultat:
{ "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 }
I det här fallet gjorde den en samlingsskanning (COLLSCAN), så som förväntat använde den inte indexet.