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

Ekskluder specifikke felter i jokertegnindeks i MongoDB

Når du opretter et wildcard-indeks i MongoDB, har du mulighed for at angive et enkelt felt, alle felter eller kun nogle.

Du har også mulighed for at udelukke visse felter. Med andre ord kan du angive alle felter undtagen for et eller flere specifikke felter.

Du kan bruge wildcardProjection parameter for at inkludere eller ekskludere specifikke feltstier fra jokertegnindekset. Denne artikel præsenterer et eksempel på at ekskludere specifikke felter i jokertegnindekset.

Eksempeldokument

Antag, at vi har en samling kaldet kæledyr med følgende dokumenter:

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

Vi kunne oprette et jokertegn på hele samlingen, mens vi ekskluderer visse felter.

Opret indekset

Her er et eksempel:

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

Output:

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

{ "$**" :1 } del er det, der skaber jokertegnindekset og wildcardProjection del er den del, der specificerer, hvilke felter der skal ekskluderes. I dette tilfælde har vi udelukket details.awards feltet og details.eats Mark. Giver dem en værdi på 0 eksplicit udelukker dem fra indekset.

Se indekset

Vi kan se indekserne på samlingen ved at kalde getIndex() metode:

db.pets.getIndexes()

Resultat:

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

Vi kan se, at der er to indekser.

  • Det første indeks er på _id Mark. Dette blev oprettet, da samlingen blev oprettet (MongoDB opretter et unikt indeks på _id-feltet under oprettelsen af ​​en samling).
  • Det andet indeks er vores jokertegn. Vi kan se, at den automatisk har fået navnet $**_1 , og det inkluderer de felter, som vi har angivet sammen med en værdi på 0 , hvilket betyder, at de eksplicit er udelukket fra indekset.

Test indekset

Vi kan også køre nogle forespørgsler for at se, om vores indeks vil blive brugt, og om de ekskluderede felter virkelig vil blive ekskluderet

Følgende forespørgsel skal bruge indekset:

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

Det bør bruge indekset, fordi vi ikke udelukkede details.type felt fra indekset.

For at teste dette kan vi tilføje explain() metode til at se forespørgselsplanen:

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

Resultat:

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

Vi kan se, at den brugte en indeksscanning (IXSCAN) på vores indeks.

I modsætning til dette er her, hvad der sker, når vi kører en forespørgsel på et af de felter, som vi udelukkede fra indekset:

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

Resultat:

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

I dette tilfælde lavede den en samlingsscanning (COLLSCAN), så som forventet brugte den ikke indekset.


  1. Hvordan kan jeg liste alle samlinger i MongoDB-skallen?

  2. Hvor står mongodb i CAP-sætningen?

  3. Hvordan indsætter man et dokument med dato i mongo?

  4. Fejl under opgradering af Mongodb fra 3.2 til 3.6