Når du opretter et jokertegn i MongoDB, har du mulighed for at angive et enkelt felt, alle felter eller kun nogle.
Du kan bruge wildcardProjection
parameter for at inkludere eller ekskludere specifikke feltstier fra jokertegnindekset. Denne artikel præsenterer et eksempel på at inkludere specifikke felter i jokertegnindekset.
Eksempeldokument
Antag, at vi har en samling kaldet kæledyr
med følgende dokumenter:
{ "_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 kunne oprette et jokertegn på hele samlingen, men kun inkludere de felter, vi ønsker.
Opret indekset
Her er et eksempel:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.type" : 1,
"details.born" : 1
}
}
)
Output:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
wildcardProjection
del er den del, der specificerer, hvilke felter der skal medtages. I dette tilfælde har vi inkluderet details.type
feltet og details.born
Mark. Giver dem værdien 1
inkluderer dem eksplicit i indekset.
Se indekset
Vi kan se indekserne på samlingen ved at kalde getIndex()
metode:
db.pets.getIndexes()
Resultat:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.type" : 1, "details.born" : 1 } } ]
Vi kan se, at der er to indekser.
- Det første indeks er på
_id
Mark. Dette blev oprettet, da samlingen blev oprettet (MongoDB opretter et unikt indeks på _id-feltet under oprettelsen af en samling). - Det andet indeks er vores jokertegn. Vi kan se, at den automatisk har fået navnet
$**_1
, og det inkluderer de felter, som vi har angivet.
Test indekset
Vi kan også køre nogle forespørgsler for at se, om vores indeks vil blive brugt eller ej.
I teorien skal følgende forespørgsel bruge indekset:
db.pets.find( { "details.type" : "Dog" } )
For at teste dette kan vi tilføje explain()
metode til at se forespørgselsplanen:
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, at den brugte en indeksscanning (IXSCAN) på vores indeks.
I modsætning til dette er her, hvad der sker, når vi kører en forespørgsel på et felt, der ikke er inkluderet i indekset:
db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()
Resultat:
{ "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 }
I dette tilfælde lavede den en samlingsscanning (COLLSCAN), så som forventet brugte den ikke indekset.