sql >> Databáze >  >> NoSQL >> MongoDB

Vyloučit konkrétní pole v indexu zástupných znaků v MongoDB

Když vytvoříte index zástupných znaků v MongoDB, máte možnost zadat jedno pole, všechna pole nebo jen některá.

Máte také možnost vyloučit některá pole. Jinými slovy, můžete zadat všechna pole kromě pro jedno nebo více konkrétních polí.

Můžete použít wildcardProjection parametr pro zahrnutí nebo vyloučení konkrétních cest polí z indexu zástupných znaků. Tento článek představuje příklad vyloučení konkrétních polí v indexu zástupných znaků.

Ukázkový dokument

Předpokládejme, že máme sbírku nazvanou pets s následujícími dokumenty:

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

Mohli bychom vytvořit zástupný index pro celou kolekci, přičemž bychom vyloučili určitá pole.

Vytvořte index

Zde je příklad:

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

Výstup:

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

{ "$**" : 1 } část je to, co vytváří index zástupných znaků a wildcardProjection část je část, která určuje, která pole se mají vyloučit. V tomto případě jsme vyloučili details.awards pole a details.eats pole. Přiřadíte jim hodnotu 0 explicitně je vyloučí z indexu.

Zobrazit rejstřík

Indexy v kolekci můžeme vidět voláním getIndexes() metoda:

db.pets.getIndexes()

Výsledek:

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

Vidíme, že existují dva indexy.

  • První index je na _id pole. Toto bylo vytvořeno při vytváření kolekce (MongoDB vytvoří jedinečný index v poli _id během vytváření kolekce).
  • Druhý index je náš zástupný index. Vidíme, že byl automaticky pojmenován $**_1 a zahrnuje pole, která jsme zadali spolu s hodnotou 0 , což znamená, že jsou z indexu výslovně vyloučeny.

Otestujte index

Můžeme také spustit nějaké dotazy, abychom zjistili, zda bude náš index použit a zda vyloučená pole budou skutečně vyloučena

Následující dotaz by měl používat index:

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

Měl by používat index, protože jsme nevyloučili details.type pole z indexu.

Abychom to otestovali, můžeme připojit explain() způsob zobrazení plánu dotazů:

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

Výsledek:

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

Vidíme, že použil indexové skenování (IXSCAN) na našem indexu.

Na rozdíl od toho zde je to, co se stane, když spustíme dotaz na jedno z polí, které jsme vyloučili z indexu:

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

Výsledek:

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

V tomto případě provedl skenování kolekce (COLLSCAN), takže podle očekávání nepoužil index.


  1. Jak používat $ regex v agregačním dotazu mongodb v rámci $match

  2. Jak ukládat velké objekty do mezipaměti pomocí mezipaměti Redis

  3. Vložte hodnotu na konkrétní pozici v poli v MongoDB

  4. Nasazení sad replik MongoDB napříč regiony na AWS