Quando crei un indice con caratteri jolly in MongoDB, hai la possibilità di specificare un singolo campo, tutti i campi o solo alcuni.
Puoi utilizzare il wildcardProjection
parametro per includere o escludere percorsi di campo specifici dall'indice dei caratteri jolly. Questo articolo presenta un esempio di inclusione 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, ma includere solo i campi che vogliamo.
Crea l'indice
Ecco un esempio:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.type" : 1,
"details.born" : 1
}
}
)
Uscita:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Il { "$**" : 1 }
parte è ciò che crea l'indice dei caratteri jolly e la wildcardProjection
parte è la parte che specifica quali campi includere. In questo caso abbiamo incluso il details.type
campo e il details.born
campo. Dando loro un valore di 1
li include esplicitamente nell'indice.
Visualizza l'indice
Possiamo visualizzare 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.type" : 1, "details.born" : 1 } } ]
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.
Verifica l'indice
Possiamo anche eseguire alcune query per vedere se il nostro indice verrà utilizzato o meno.
In teoria, la seguente query dovrebbe utilizzare l'indice:
db.pets.find( { "details.type" : "Dog" } )
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 un campo che non incluso nell'indice:
db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()
Risultato:
{ "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 }
In questo caso ha eseguito una scansione della raccolta (COLLSCAN), quindi, come previsto, non ha utilizzato l'indice.