Cuando crea un índice comodín en MongoDB, tiene la opción de especificar un solo campo, todos los campos o solo algunos.
También tiene la opción de excluir ciertos campos. En otras palabras, puede especificar todos los campos excepto para uno o más campos específicos.
Puedes usar la wildcardProjection
parámetro para incluir o excluir rutas de campo específicas del índice comodín. Este artículo presenta un ejemplo de exclusión de campos específicos en el índice de comodines.
Documento de ejemplo
Supongamos que tenemos una colección llamada pets
con los siguientes documentos:
{ "_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") } }
Podríamos crear un índice comodín en toda la colección, excluyendo ciertos campos.
Crear el índice
He aquí un ejemplo:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Salida:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
El { "$**" : 1 }
parte es lo que crea el índice comodín y la wildcardProjection
part es la parte que especifica qué campos excluir. En este caso, hemos excluido los details.awards
y el campo details.eats
campo. Dándoles un valor de 0
los excluye explícitamente del índice.
Ver el índice
Podemos ver los índices de la colección llamando a getIndexes()
método:
db.pets.getIndexes()
Resultado:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Podemos ver que hay dos índices.
- El primer índice está en
_id
campo. Esto se creó cuando se creó la colección (MongoDB crea un índice único en el campo _id durante la creación de una colección). - El segundo índice es nuestro índice comodín. Podemos ver que se ha nombrado automáticamente
$**_1
, e incluye los campos que especificamos junto con un valor de0
, lo que significa que están explícitamente excluidos del índice.
Prueba el índice
También podemos ejecutar algunas consultas para ver si se usará nuestro índice y si los campos excluidos realmente se excluirán
La siguiente consulta debe usar el índice:
db.pets.find( { "details.type" : "Dog" } )
Debería usar el índice porque no excluimos el details.type
campo del índice.
Para probar esto, podemos agregar explain()
método para ver el plan de consulta:
db.pets.find( { "details.type" : "Dog" } ).explain()
Resultado:
{ "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 }
Podemos ver que usó un escaneo de índice (IXSCAN) en nuestro índice.
En contraste con esto, esto es lo que sucede cuando ejecutamos una consulta en uno de los campos que excluimos del índice:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Resultado:
{ "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 }
En este caso, realizó un análisis de la colección (COLLSCAN), por lo que, como era de esperar, no utilizó el índice.