MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Изключете специфични полета в индекса на заместващи символи в MongoDB

Когато създавате заместващ индекс в MongoDB, имате възможност да посочите едно поле, всички полета или само някои.

Освен това имате възможност да изключите определени полета. С други думи, можете да посочите всички полета освен за едно или повече конкретни полета.

Можете да използвате wildcardProjection параметър за включване или изключване на конкретни пътеки на полета от заместващия индекс. Тази статия представя пример за изключване на конкретни полета в индекса за заместващи знаци.

Примерен документ

Да предположим, че имаме колекция, наречена pets със следните документи:

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

Можем да създадем заместващ индекс за цялата колекция, като същевременно изключим определени полета.

Създайте индекса

Ето един пример:

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

Изход:

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

{ "$**" : 1 } част е това, което създава заместващия индекс и wildcardProjection част е частта, която определя кои полета да се изключат. В този случай изключихме details.awards полето и details.eats поле. Давайки им стойност от 0 изрично ги изключва от индекса.

Преглед на индекса

Можем да видим индексите на колекцията, като извикаме getIndexes() метод:

db.pets.getIndexes()

Резултат:

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

Виждаме, че има два индекса.

  • Първият индекс е на _id поле. Това е създадено при създаването на колекцията (MongoDB създава уникален индекс в полето _id по време на създаването на колекция).
  • Вторият индекс е нашият заместващ индекс. Можем да видим, че автоматично е наречен $**_1 , и включва полетата, които посочихме заедно със стойност 0 , което означава, че те са изрично изключени от индекса.

Тествайте индекса

Можем също да изпълним някои заявки, за да видим дали нашият индекс ще бъде използван и дали изключените полета наистина ще бъдат изключени

Следната заявка трябва да използва индекса:

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

Трябва да използва индекса, защото не изключихме details.type поле от индекса.

За да тестваме това, можем да добавим explain() метод за преглед на плана на заявката:

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

Резултат:

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

Можем да видим, че използва индексно сканиране (IXSCAN) на нашия индекс.

За разлика от това, ето какво се случва, когато изпълним заявка в едно от полетата, които изключихме от индекса:

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

Резултат:

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

В този случай той направи сканиране на колекция (COLLSCAN), така че както се очакваше, не използва индекса.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. 3 начина за пускане на индекс в MongoDB

  2. CouchDB срещу MongoDB:10 неща, които трябва да знаете

  3. Ръководство за конфигуриране на Load Balancer в MongoDB Sharded Cluster

  4. Model.find() връща празен в mongoose

  5. 3 начина да получите седмицата от среща в MongoDB