MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Einbeziehen bestimmter Felder in einen Wildcard-Index in MongoDB

Wenn Sie einen Wildcard-Index in MongoDB erstellen, haben Sie die Möglichkeit, ein einzelnes Feld, alle Felder oder nur einige anzugeben.

Sie können die wildcardProjection verwenden -Parameter, um bestimmte Feldpfade in den Wildcard-Index aufzunehmen oder daraus auszuschließen. Dieser Artikel enthält ein Beispiel für die Aufnahme bestimmter Felder in den Wildcard-Index.

Beispieldokument

Angenommen, wir haben eine Sammlung namens pets mit folgenden Dokumenten:

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

Wir könnten einen Wildcard-Index für die gesamte Sammlung erstellen, aber nur die gewünschten Felder einbeziehen.

Index erstellen

Hier ist ein Beispiel:

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

Ausgabe:

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

Der { "$**" : 1 } Teil erstellt den Wildcard-Index und die wildcardProjection part ist der Teil, der angibt, welche Felder eingeschlossen werden sollen. In diesem Fall haben wir den details.type eingefügt Feld und die details.born Feld. Geben Sie ihnen den Wert 1 nimmt sie explizit in den Index auf.

Zeigen Sie den Index an

Wir können die Indizes der Sammlung anzeigen, indem wir getIndexes() aufrufen Methode:

db.pets.getIndexes()

Ergebnis:

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

Wir können sehen, dass es zwei Indizes gibt.

  • Der erste Index ist auf _id Feld. Dies wurde erstellt, als die Sammlung erstellt wurde (MongoDB erstellt während der Erstellung einer Sammlung einen eindeutigen Index für das Feld _id).
  • Der zweite Index ist unser Wildcard-Index. Wir können sehen, dass es automatisch $**_1 benannt wurde , und es enthält die Felder, die wir angegeben haben.

Index testen

Wir können auch einige Abfragen ausführen, um zu sehen, ob unser Index verwendet wird oder nicht.

Theoretisch sollte die folgende Abfrage den Index verwenden:

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

Um dies zu testen, können wir explain() anhängen Methode zum Anzeigen des Abfrageplans:

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

Ergebnis:

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

Wir können sehen, dass es einen Index-Scan (IXSCAN) für unseren Index verwendet hat.

Im Gegensatz dazu passiert Folgendes, wenn wir eine Abfrage für ein Feld ausführen, das nicht ist in den Index aufgenommen:

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

Ergebnis:

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

In diesem Fall wurde ein Sammlungsscan (COLLSCAN) durchgeführt, sodass der Index wie erwartet nicht verwendet wurde.