sql >> Database >  >> NoSQL >> MongoDB

Specifieke velden uitsluiten in wildcard-index in MongoDB

Wanneer u een wildcard-index in MongoDB maakt, heeft u de mogelijkheid om een ​​enkel veld, alle velden of slechts enkele op te geven.

U heeft ook de mogelijkheid om bepaalde velden uit te sluiten. Met andere woorden, u kunt alle velden specificeren behalve voor een of meer specifieke velden.

U kunt de wildcardProjection . gebruiken parameter om specifieke veldpaden op te nemen of uit te sluiten van de wildcardindex. Dit artikel geeft een voorbeeld van het uitsluiten van specifieke velden in de wildcard-index.

Voorbeelddocument

Stel dat we een verzameling hebben met de naam pets met de volgende documenten:

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

We zouden een wildcard-index kunnen maken voor de hele collectie, terwijl we bepaalde velden uitsluiten.

De index maken

Hier is een voorbeeld:

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

Uitgang:

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

De { "$**" : 1 } een deel is wat de wildcard-index maakt, en de wildcardProjection deel is het deel dat aangeeft welke velden moeten worden uitgesloten. In dit geval hebben we de details.awards uitgesloten veld en de details.eats veld. Geef ze een waarde van 0 sluit ze expliciet uit van de index.

Bekijk de index

We kunnen de indexen van de collectie zien door de getIndexes() . aan te roepen methode:

db.pets.getIndexes()

Resultaat:

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

We kunnen zien dat er twee indexen zijn.

  • De eerste index staat op de _id veld. Dit is gemaakt toen de verzameling werd gemaakt (MongoDB creëert een unieke index op het _id-veld tijdens het maken van een verzameling).
  • De tweede index is onze wildcard-index. We kunnen zien dat het automatisch de naam $**_1 heeft gekregen , en het bevat de velden die we hebben gespecificeerd samen met een waarde van 0 , wat betekent dat ze expliciet zijn uitgesloten van de index.

Test de index

We kunnen ook enkele zoekopdrachten uitvoeren om te zien of onze index zal worden gebruikt en of de uitgesloten velden echt worden uitgesloten

De volgende query moet de index gebruiken:

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

Het zou de index moeten gebruiken omdat we de details.type niet hebben uitgesloten veld uit de index.

Om dit te testen, kunnen we de explain() . toevoegen methode om het zoekplan te bekijken:

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

Resultaat:

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

We kunnen zien dat het een indexscan (IXSCAN) op onze index heeft gebruikt.

In tegenstelling hiermee, is dit wat er gebeurt als we een query uitvoeren op een van de velden die we uitgesloten uit de index:

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

Resultaat:

{
	"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 dit geval deed het een collectiescan (COLLSCAN), dus zoals verwacht gebruikte het de index niet.


  1. Maak verbinding met host mongodb vanuit docker-container

  2. Aan de slag met MongoDB-gebruikersbeheer

  3. Grote gegevensworkflows met panda's

  4. Wat zijn de onderliggende verschillen tussen select, epoll, kqueue en evport?