Quando crei un indice con caratteri jolly in MongoDB, hai la possibilità di specificare un singolo campo, tutti i campi o solo alcuni.
Hai anche la possibilità di escludere determinati campi. In altre parole, puoi specificare tutti i campi tranne per uno o più campi specifici.
Puoi utilizzare il wildcardProjection
parametro per includere o escludere percorsi di campo specifici dall'indice dei caratteri jolly. Questo articolo presenta un esempio di esclusione di campi specifici nell'indice dei caratteri jolly.
Documento di esempio
Supponiamo di avere una collezione chiamata pets
con i seguenti documenti:
{ "_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") } }
Potremmo creare un indice jolly sull'intera collezione, escludendo alcuni campi.
Crea l'indice
Ecco un esempio:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Uscita:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Il { "$**" : 1 }
parte è ciò che crea l'indice dei caratteri jolly e la wildcardProjection
part è la parte che specifica quali campi escludere. In questo caso abbiamo escluso i details.awards
e il campo details.eats
campo. Dando loro un valore di 0
li esclude esplicitamente dall'indice.
Visualizza l'indice
Possiamo vedere gli indici sulla collezione chiamando getIndexes()
metodo:
db.pets.getIndexes()
Risultato:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Possiamo vedere che ci sono due indici.
- Il primo indice è su
_id
campo. Questo è stato creato quando è stata creata la raccolta (MongoDB crea un indice univoco sul campo _id durante la creazione di una raccolta). - Il secondo indice è il nostro indice jolly. Possiamo vedere che è stato automaticamente chiamato
$**_1
e include i campi che abbiamo specificato insieme a un valore di0
, il che significa che sono esplicitamente esclusi dall'indice.
Verifica l'indice
Possiamo anche eseguire alcune query per vedere se il nostro indice verrà utilizzato e se i campi esclusi verranno davvero esclusi
La query seguente dovrebbe utilizzare l'indice:
db.pets.find( { "details.type" : "Dog" } )
Dovrebbe utilizzare l'indice perché non abbiamo escluso il details.type
campo dall'indice.
Per verificarlo, possiamo aggiungere explain()
metodo per visualizzare il piano di query:
db.pets.find( { "details.type" : "Dog" } ).explain()
Risultato:
{ "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 }
Possiamo vedere che ha utilizzato una scansione dell'indice (IXSCAN) sul nostro indice.
Al contrario, ecco cosa succede quando eseguiamo una query su uno dei campi che abbiamo escluso dall'indice:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Risultato:
{ "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 questo caso ha eseguito una scansione della raccolta (COLLSCAN), quindi, come previsto, non ha utilizzato l'indice.