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

Opret et wildcard-indeks i MongoDB

Der er flere måder at oprette et indeks på i MongoDB, og fra MongoDB 4.2 kan vi oprette jokertegnindekser.

Et wildcard-indeks kan opfattes som en slags filter, der automatisk matcher ethvert felt, underdokument eller matrix i en samling og derefter indekserer disse matches.

Dette kan være nyttigt, hvis dine dokumenter indeholder ustrukturerede data med forskellige felter i forskellige hierarkier. I sådanne tilfælde er der ingen måde at forudsige, hvad indekset skal være, fordi du ikke ved, hvilke data der vil være i hvert dokument.

Wildcard-indekser kan være nyttige med sådanne ustrukturerede data, fordi de indekserer alle skalarværdier i feltet, automatisk gentages i alle underdokumenter eller arrays og indekserer alle skalarfelter i underdokumentet/arrayet.

Eksempelsamling

Wildcard-indekser er ikke for hver samling. Du vil kun oprette et jokertegn på visse samlinger med dokumenter, der indeholder ustrukturerede data med forskellige felter i forskellige hierarkier.

Nedenfor er et eksempel på en samling kaldet pets der kan være en god kandidat til et jokertegn:

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

Hvert af de 3 dokumenter i denne samling har en details felt, men de indeholder forskellige felter inden for dette felt. Det er ikke konsekvent. Dette ville normalt gøre det svært at oprette et indeks, fordi vi ikke ved, hvilke felter der skal være i hvert dokument. Vi ville sandsynligvis være nødt til at oprette flere indekser efter omhyggelig analyse af de mulige dokumentstrukturer.

Heldigvis kan vi oprette et jokertegn.

Men lad os først se på, hvordan en forespørgselsplan kan se ud, når du forespørger i et af disse felter. Forestil dig, at vi gerne vil finde ud af, hvilken hund der fik prisen "Hurtigste Hund" ved New York Marathon. Vi kunne gøre følgende:

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

Og hvis vi ville tjekke forespørgselsplanen, kunne vi tilføje explain() til slutningen:

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

Hvilket returnerer følgende:

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

Hvilket fortæller os, at den skulle lave en samlingsscanning (COLLSCAN), hvilket betyder, at den skal scanne gennem hvert dokument, der leder efter feltet.

Opret et jokertegnsindeks

Her er et eksempel på oprettelse af et jokertegn for ovenstående samling.

db.pets.createIndex({ "details.$**": 1 });

Output:

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

Det er det. Jokertegnindekset er blevet oprettet.

For at oprette jokertegnsindekset brugte vi feltnavnet, som vi ønskede at oprette indekset på (i dette tilfælde details felt), så tilføjede vi det med en prik (. ), og derefter den vigtige del, $** del.

$** angiver, at der skal oprettes et wildcard-indeks fra dette felt og alle dets underdokumenter.

Præfiks til $** med details begrænser jokertegnsindeksets omfang til kun details felt.

Lad os nu tjekke forespørgselsplanen for den førnævnte forespørgsel igen:

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

Resultat:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "7DFA23ED",
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"$_path" : 1,
					"details.awards.New York Marathon" : 1
				},
				"indexName" : "details.$**_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"$_path" : [ ],
					"details.awards.New York Marathon" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"$_path" : [
						"[\"details.awards.New York Marathon\", \"details.awards.New York Marathon\"]"
					],
					"details.awards.New York Marathon" : [
						"[\"Fastest Dog\", \"Fastest Dog\"]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Denne gang er samlingsscanningen (COLLSCAN) blevet erstattet af en indeksscanning (IXSCAN) på vores nyoprettede jokertegn.

Hvert felt i vores details felt er blevet indekseret som en sti/værdi, og der er en indgang i indekset for hvert felt i hierarkiet. Hvor feltværdien er et underdokument (såsom vores. awards). felt), er indekseringen gået ned i underdokumentet og gentaget processen.

Oprettelse af et wildcard-indeks på alle feltstier

I det foregående eksempel oprettede vi et jokertegn på en enkelt feltsti. Det er muligt at oprette et jokertegn på alle feltstier ved blot at bruge $** uden at sætte et felt foran det.

For eksempel kunne vi have gjort dette:

db.pets.createIndex({ "$**": 1 });

Det ville have skabt et jokertegn på alle feltstier.

Faktisk er det ikke helt rigtigt. Som standard oprettes jokertegnsindekser ikke på _id Mark. For at inkludere _id felt, skal du inkludere det i en wildcardProjection dokument.

Kan du ikke oprette jokertegnindekser? Tjek denne indstilling.

mongod featureCompatibilityVersion skal være mindst 4.2 for at oprette jokertegnindekser.

Du kan kontrollere denne indstilling med følgende kode:

db.adminCommand( 
    { 
        getParameter: 1, 
        featureCompatibilityVersion: 1 
    } 
)

Du kan indstille det ved hjælp af setFeatureCompatibilityVersion kommando:

db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )

setFeatureCompatibilityVersion kommandoen skal køres i admin database.


  1. Opsætning af ElastiCache Redis med Elastic BeanStalk + Django

  2. Mongoose opdatering/upsert?

  3. rangordne leaderboard i mongo med omkringliggende spillere

  4. Hvordan kører jeg Redis på Windows 32 bit?