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

Inkluder specifikke felter i et wildcard-indeks i MongoDB

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

Du kan bruge wildcardProjection parameter for at inkludere eller ekskludere specifikke feltstier fra jokertegnindekset. Denne artikel præsenterer et eksempel på at inkludere 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, men kun inkludere de felter, vi ønsker.

Opret indekset

Her er et eksempel:

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

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 medtages. I dette tilfælde har vi inkluderet details.type feltet og details.born Mark. Giver dem værdien 1 inkluderer dem eksplicit i 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.type" : 1,
			"details.born" : 1
		}
	}
]

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.

Test indekset

Vi kan også køre nogle forespørgsler for at se, om vores indeks vil blive brugt eller ej.

I teorien skal følgende forespørgsel bruge indekset:

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

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 felt, der ikke er inkluderet i indekset:

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" : "EC0D5185",
		"winningPlan" : {
			"stage" : "COLLSCAN",
			"filter" : {
				"details.awards.New York Marathon" : {
					"$eq" : "Fastest Dog"
				}
			},
			"direction" : "forward"
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

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


  1. Forberedelse af en MongoDB-server til produktion

  2. Redis opdaterer ikke, når mange forespørgsler på én gang

  3. Redis/Jedis intet enkelt fejlpunkt og automatiseret failover

  4. SQL RPAD()