sql >> Databasteknik >  >> NoSQL >> MongoDB

Inkludera specifika fält i ett 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 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 inkludera 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 på hela samlingen, men bara inkludera de fält vi vill ha.

Skapa indexet

Här är ett exempel:

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

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 inkluderas. I det här fallet har vi inkluderat details.type och details.born fält. Ge dem värdet 1 inkluderar dem uttryckligen i 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.type" : 1,
			"details.born" : 1
		}
	}
]

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.

Testa indexet

Vi kan också köra några frågor för att se om vårt index kommer att användas eller inte.

I teorin bör följande fråga använda indexet:

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

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 fält som inte ingår i indexet:

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


  1. Hur man ersätter befintliga dokument när man importerar en fil till MongoDB

  2. SocketTimeout med öppnad anslutning i MongoDB

  3. 7 sätt att kontrollera din MongoDB-version

  4. Hur utför jag en id-matrisfråga i Mongoose?