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

Escludi campi specifici nell'indice dei 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.

Hai anche la possibilità di escludere determinati campi. In altre parole, puoi specificare tutti i campi tranne per uno o più campi specifici.

Puoi utilizzare il wildcardProjection parametro per includere o escludere percorsi di campo specifici dall'indice dei caratteri jolly. Questo articolo presenta un esempio di esclusione 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, escludendo alcuni campi.

Crea l'indice

Ecco un esempio:

db.pets.createIndex(
  { "$**" : 1 },
  {
    "wildcardProjection" : {
      "details.awards" : 0,
      "details.eats" : 0
    }
  }
)

Uscita:

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

Il { "$**" : 1 } parte è ciò che crea l'indice dei caratteri jolly e la wildcardProjection part è la parte che specifica quali campi escludere. In questo caso abbiamo escluso i details.awards e il campo details.eats campo. Dando loro un valore di 0 li esclude esplicitamente dall'indice.

Visualizza l'indice

Possiamo vedere 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.awards" : 0,
			"details.eats" : 0
		}
	}
]

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 insieme a un valore di 0 , il che significa che sono esplicitamente esclusi dall'indice.

Verifica l'indice

Possiamo anche eseguire alcune query per vedere se il nostro indice verrà utilizzato e se i campi esclusi verranno davvero esclusi

La query seguente dovrebbe utilizzare l'indice:

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

Dovrebbe utilizzare l'indice perché non abbiamo escluso il details.type campo dall'indice.

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 uno dei campi che abbiamo escluso dall'indice:

db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()

Risultato:

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

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