sql >> Databasteknik >  >> NoSQL >> MongoDB

Exkludera specifika fält i jokerteckenindex i MongoDB

När du skapar ett jokertecken i MongoDB har du möjlighet att ange ett enda fält, alla fält eller bara några.

Du har även möjlighet att utesluta vissa fält. Med andra ord kan du ange alla fält utom för ett eller flera specifika fält.

Du kan använda wildcardProjection parameter för att inkludera eller exkludera specifika fältsökvägar från jokerteckenindexet. Den här artikeln presenterar ett exempel på att exkludera specifika fält i jokerteckenindexet.

Exempeldokument

Anta att vi har en samling som heter pets med följande dokument:

{
	"_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 skulle kunna skapa ett jokertecken för hela samlingen, samtidigt som vi utesluter vissa fält.

Skapa indexet

Här är ett exempel:

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

Utdata:

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

{ "$**" : 1 } del är det som skapar jokerteckenindexet och wildcardProjection del är den del som anger vilka fält som ska exkluderas. I det här fallet har vi uteslutit details.awards och details.eats fält. Ge dem värdet 0 exkluderar dem uttryckligen från indexet.

Visa indexet

Vi kan se indexen på samlingen genom att anropa getIndexes() metod:

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 att det finns två index.

  • Det första indexet finns på _id fält. Detta skapades när samlingen skapades (MongoDB skapar ett unikt index på _id-fältet under skapandet av en samling).
  • Det andra indexet är vårt jokertecken. Vi kan se att den automatiskt har fått namnet $**_1 , och det inkluderar fälten som vi angav tillsammans med värdet 0 , vilket betyder att de uttryckligen är exkluderade från indexet.

Testa indexet

Vi kan också köra några frågor för att se om vårt index kommer att användas och om de uteslutna fälten verkligen kommer att uteslutas

Följande fråga ska använda indexet:

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

Den bör använda indexet eftersom vi inte exkluderade details.type fält från indexet.

För att testa detta kan vi lägga till explain() metod för att visa frågeplanen:

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 att den använde en indexskanning (IXSCAN) på vårt index.

I motsats till detta, här är vad som händer när vi kör en fråga på ett av fälten som vi uteslutit från indexet:

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 det här fallet gjorde den en samlingsskanning (COLLSCAN), så som förväntat använde den inte indexet.


  1. Skapar hirdis Redis-biblioteket en egen tråd för asynkrona återuppringningar

  2. MongoDB $summa och $avg av underdokument

  3. JedisPoolConfig kan inte tilldelas till GenericObjectPoolConfig

  4. Spring Boot anslut Mysql och MongoDb