Ao criar um índice curinga no MongoDB, você tem a opção de especificar um único campo, todos os campos ou apenas alguns.
Você também tem a opção de excluir determinados campos. Em outras palavras, você pode especificar todos os campos exceto para um ou mais campos específicos.
Você pode usar a
wildcardProjection
parâmetro para incluir ou excluir caminhos de campo específicos do índice curinga. Este artigo apresenta um exemplo de exclusão de campos específicos no índice curinga. Exemplo de documento
Suponha que tenhamos uma coleção chamada
pets
com os seguintes 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") } }
Poderíamos criar um índice curinga em toda a coleção, excluindo certos campos.
Criar o Índice
Aqui está um exemplo:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Saída:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
O
{ "$**" : 1 }
parte é o que cria o índice curinga e o wildcardProjection
parte é a parte que especifica quais campos excluir. Nesse caso, excluímos os details.awards
campo e o details.eats
campo. Dando a eles um valor de 0
explicitamente os exclui do índice. Visualizar o Índice
Podemos ver os índices na coleção chamando o método
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 existem dois índices.
- O primeiro índice está no
_id
campo. Isso foi criado quando a coleção foi criada (o MongoDB cria um índice exclusivo no campo _id durante a criação de uma coleção). - O segundo índice é nosso índice curinga. Podemos ver que foi nomeado automaticamente
$**_1
, e inclui os campos que especificamos junto com um valor de0
, o que significa que eles são explicitamente excluídos do índice.
Teste o índice
Também podemos executar algumas consultas para ver se nosso índice será usado e se os campos excluídos realmente serão excluídos
A consulta a seguir deve usar o índice:
db.pets.find( { "details.type" : "Dog" } )
Ele deve usar o índice porque não excluímos o
details.type
campo do índice. Para testar isso, podemos anexar o
explain()
método para visualizar o plano 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 ele usou uma varredura de índice (IXSCAN) em nosso índice.
Em contraste com isso, veja o que acontece quando executamos uma consulta em um dos campos que excluímos do í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 }
Neste caso ele fez uma varredura de coleção (COLLSCAN), então como esperado, não utilizou o índice.