Lorsque vous créez un index générique dans MongoDB, vous avez la possibilité de spécifier un seul champ, tous les champs ou seulement certains.
Vous pouvez utiliser le wildcardProjection
paramètre pour inclure ou exclure des chemins de champ spécifiques de l'index générique. Cet article présente un exemple d'inclusion de champs spécifiques dans l'index générique.
Exemple de document
Supposons que nous ayons une collection appelée pets
avec les documents suivants :
{ "_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") } }
Nous pourrions créer un index générique sur l'ensemble de la collection, mais n'inclure que les champs souhaités.
Créer l'index
Voici un exemple :
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.type" : 1,
"details.born" : 1
}
}
)
Sortie :
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Le { "$**" : 1 }
part est ce qui crée l'index générique, et le wildcardProjection
part est la partie qui spécifie les champs à inclure. Dans ce cas, nous avons inclus le details.type
champ et le details.born
domaine. En leur donnant une valeur de 1
les inclut explicitement dans l'index.
Afficher l'index
Nous pouvons afficher les index sur la collection en appelant le getIndexes()
méthode :
db.pets.getIndexes()
Résultat :
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.type" : 1, "details.born" : 1 } } ]
On voit qu'il y a deux index.
- Le premier index est sur le
_id
domaine. Celui-ci a été créé lors de la création de la collection (MongoDB crée un index unique sur le champ _id lors de la création d'une collection). - Le deuxième index est notre index générique. Nous pouvons voir qu'il a été nommé automatiquement
$**_1
, et il inclut les champs que nous avons spécifiés.
Tester l'index
Nous pouvons également exécuter des requêtes pour voir si notre index sera utilisé ou non.
En théorie, la requête suivante devrait utiliser l'index :
db.pets.find( { "details.type" : "Dog" } )
Pour tester cela, nous pouvons ajouter le explain()
méthode pour afficher le plan de requête :
db.pets.find( { "details.type" : "Dog" } ).explain()
Résultat :
{ "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 }
Nous pouvons voir qu'il a utilisé une analyse d'index (IXSCAN) sur notre index.
En revanche, voici ce qui se passe lorsque nous exécutons une requête sur un champ qui n'est pas inclus dans l'index :
db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()
Résultat :
{ "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 }
Dans ce cas, il a fait une analyse de collection (COLLSCAN), donc comme prévu, il n'a pas utilisé l'index.