MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Excluir campos específicos no índice curinga no MongoDB


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 de 0 , 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.