sql >> Base de Datos >  >> NoSQL >> MongoDB

Incluir campos específicos en un índice comodín en MongoDB

Cuando crea un índice comodín en MongoDB, tiene la opción de especificar un solo campo, todos los campos o solo algunos.

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 cómo incluir 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, pero solo incluir los campos que queremos.

Crear el índice

He aquí un ejemplo:

db.pets.createIndex(
  { "$**" : 1 },
  {
    "wildcardProjection" : {
      "details.type" : 1,
      "details.born" : 1
    }
  }
)

Salida:

{
	"createdCollectionAutomatically" : false,
	"numIndexesBefore" : 1,
	"numIndexesAfter" : 2,
	"ok" : 1
}

El { "$**" : 1 } parte es lo que crea el índice comodín y la wildcardProjection parte es la parte que especifica qué campos incluir. En este caso hemos incluido el details.type y el campo details.born campo. Dándoles un valor de 1 los incluye explícitamente en el í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.type" : 1,
			"details.born" : 1
		}
	}
]

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.

Prueba el índice

También podemos ejecutar algunas consultas para ver si nuestro índice se utilizará o no.

En teoría, la siguiente consulta debería usar el índice:

db.pets.find( { "details.type" : "Dog" } )

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 un campo que no incluido en el índice:

db.pets.find( { "details.awards.New York Marathon" : "Fastest Dog" } ).explain()

Resultado:

{
	"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
}

En este caso, realizó un análisis de la colección (COLLSCAN), por lo que, como era de esperar, no utilizó el índice.