MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Includi campi specifici in un indice con caratteri jolly in MongoDB

Quando crei un indice con caratteri jolly in MongoDB, hai la possibilità di specificare un singolo campo, tutti i campi o solo alcuni.

Puoi utilizzare il wildcardProjection parametro per includere o escludere percorsi di campo specifici dall'indice dei caratteri jolly. Questo articolo presenta un esempio di inclusione di campi specifici nell'indice dei caratteri jolly.

Documento di esempio

Supponiamo di avere una collezione chiamata pets con i seguenti documenti:

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

Potremmo creare un indice jolly sull'intera collezione, ma includere solo i campi che vogliamo.

Crea l'indice

Ecco un esempio:

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

Uscita:

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

Il { "$**" : 1 } parte è ciò che crea l'indice dei caratteri jolly e la wildcardProjection parte è la parte che specifica quali campi includere. In questo caso abbiamo incluso il details.type campo e il details.born campo. Dando loro un valore di 1 li include esplicitamente nell'indice.

Visualizza l'indice

Possiamo visualizzare gli indici sulla collezione chiamando getIndexes() metodo:

db.pets.getIndexes()

Risultato:

[
	{
		"v" : 2,
		"key" : {
			"_id" : 1
		},
		"name" : "_id_"
	},
	{
		"v" : 2,
		"key" : {
			"$**" : 1
		},
		"name" : "$**_1",
		"wildcardProjection" : {
			"details.type" : 1,
			"details.born" : 1
		}
	}
]

Possiamo vedere che ci sono due indici.

  • Il primo indice è su _id campo. Questo è stato creato quando è stata creata la raccolta (MongoDB crea un indice univoco sul campo _id durante la creazione di una raccolta).
  • Il secondo indice è il nostro indice jolly. Possiamo vedere che è stato automaticamente chiamato $**_1 e include i campi che abbiamo specificato.

Verifica l'indice

Possiamo anche eseguire alcune query per vedere se il nostro indice verrà utilizzato o meno.

In teoria, la seguente query dovrebbe utilizzare l'indice:

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

Per verificarlo, possiamo aggiungere explain() metodo per visualizzare il piano di query:

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

Risultato:

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

Possiamo vedere che ha utilizzato una scansione dell'indice (IXSCAN) sul nostro indice.

Al contrario, ecco cosa succede quando eseguiamo una query su un campo che non incluso nell'indice:

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

Risultato:

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

In questo caso ha eseguito una scansione della raccolta (COLLSCAN), quindi, come previsto, non ha utilizzato l'indice.