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

Schließen Sie bestimmte Felder im Wildcard-Index in MongoDB aus

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

Sie haben auch die Möglichkeit, bestimmte Felder auszuschließen. Mit anderen Worten, Sie können alle Felder außer angeben für ein oder mehrere spezifische Felder.

Sie können die wildcardProjection verwenden -Parameter, um bestimmte Feldpfade in den Wildcard-Index aufzunehmen oder daraus auszuschließen. Dieser Artikel zeigt ein Beispiel für das Ausschließen bestimmter Felder im 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 und dabei bestimmte Felder ausschließen.

Index erstellen

Hier ist ein Beispiel:

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

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 ausgeschlossen werden sollen. In diesem Fall haben wir die details.awards ausgeschlossen Feld und die details.eats Feld. Geben Sie ihnen den Wert 0 schließt sie explizit aus dem Index aus.

Zeigen Sie den Index an

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

db.pets.getIndexes()

Ergebnis:

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

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 von uns angegebenen Felder zusammen mit einem Wert von 0 , was bedeutet, dass sie explizit aus dem Index ausgeschlossen werden.

Index testen

Wir können auch einige Abfragen ausführen, um zu sehen, ob unser Index verwendet wird und ob die ausgeschlossenen Felder wirklich ausgeschlossen werden

Die folgende Abfrage sollte den Index verwenden:

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

Es sollte den Index verwenden, da wir details.type nicht ausgeschlossen haben Feld aus dem Index.

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 eines der Felder ausführen, die wir ausgeschlossen haben aus dem Index:

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

Ergebnis:

{
	"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 diesem Fall wurde ein Sammlungsscan (COLLSCAN) durchgeführt, sodass der Index wie erwartet nicht verwendet wurde.