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

Създайте индекс за заместващи символи в MongoDB

Има няколко начина за създаване на индекс в MongoDB и от MongoDB 4.2 можем да създаваме индекси с заместващи знаци.

Индексът с заместващи знаци може да се разглежда като вид филтър, който автоматично съпоставя всяко поле, поддокумент или масив в колекция и след това индексира тези съвпадения.

Това може да бъде полезно, ако вашите документи съдържат неструктурирани данни с различни полета в различни йерархии. В такива случаи няма начин да се предвиди какъв трябва да бъде индексът, защото не знаете какви данни ще има във всеки документ.

Индексите с заместващи знаци могат да бъдат полезни с такива неструктурирани данни, тъй като индексират всички скаларни стойности на полето, автоматично се рекурсират във всички поддокументи или масиви и индексират всички скаларни полета в поддокумента/масива.

Примерна колекция

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

По-долу е даден пример за колекция, наречена 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")
	}
}

Всеки от 3-те документа в тази колекция има details поле, но те съдържат различни полета в това поле. Не е последователно. Това обикновено затруднява създаването на индекс, защото не знаем какви полета ще бъдат във всеки документ. Вероятно ще трябва да създадем множество индекси, след внимателен анализ на възможните структури на документи.

За щастие можем да създадем заместващ индекс.

Но първо, нека да разгледаме как може да изглежда планът за заявка при запитване към едно от тези полета. Представете си, че искаме да разберем кое куче получи наградата „Най-бързото куче“ на маратона в Ню Йорк. Бихме могли да направим следното:

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

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

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

Което връща следното:

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

Което ни казва, че ще направи сканиране на колекция (COLLSCAN), което означава, че трябва да сканира всеки документ, търсещ полето.

Създайте индекс с заместващи знаци

Ето пример за създаване на заместващ индекс за горната колекция.

db.pets.createIndex({ "details.$**": 1 });

Изход:

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

Това е. Индексът на заместващи символи е създаден.

За да създадем заместващия индекс, използвахме името на полето, върху което искахме да създадем индекса (в този случай details поле), след което го добавихме с точка (. ), а след това важната част, $** част.

$** указва, че от това поле и всички негови поддокументи трябва да се създаде заместващ индекс.

Префикс на $** с details ограничава обхвата на заместващия индекс само до details поле.

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

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

Резултат:

{
	"queryPlanner" : {
		"plannerVersion" : 1,
		"namespace" : "PetHotel.pets",
		"indexFilterSet" : false,
		"parsedQuery" : {
			"details.awards.New York Marathon" : {
				"$eq" : "Fastest Dog"
			}
		},
		"queryHash" : "EC0D5185",
		"planCacheKey" : "7DFA23ED",
		"winningPlan" : {
			"stage" : "FETCH",
			"inputStage" : {
				"stage" : "IXSCAN",
				"keyPattern" : {
					"$_path" : 1,
					"details.awards.New York Marathon" : 1
				},
				"indexName" : "details.$**_1",
				"isMultiKey" : false,
				"multiKeyPaths" : {
					"$_path" : [ ],
					"details.awards.New York Marathon" : [ ]
				},
				"isUnique" : false,
				"isSparse" : false,
				"isPartial" : false,
				"indexVersion" : 2,
				"direction" : "forward",
				"indexBounds" : {
					"$_path" : [
						"[\"details.awards.New York Marathon\", \"details.awards.New York Marathon\"]"
					],
					"details.awards.New York Marathon" : [
						"[\"Fastest Dog\", \"Fastest Dog\"]"
					]
				}
			}
		},
		"rejectedPlans" : [ ]
	},
	"ok" : 1
}

Този път сканирането на колекцията (COLLSCAN) беше заменено от сканиране на индекс (IXSCAN) на нашия новосъздадения индекс с заместващи символи.

Всяко поле в нашите details полето е индексирано като път/стойност и има запис в индекса за всяко поле в йерархията. Когато стойността на полето е поддокумент (като нашите. awards). поле), индексирането се е спуснало в поддокумента и повтори процеса.

Създаване на индекс за заместващи знаци за всички пътища на полета

В предишния пример създадохме индекс за заместващи знаци в едно поле. Възможно е да създадете индекс на заместващи знаци за всички полета, просто като използвате $** без да се поставя префикс с поле.

Например, можехме да направим това:

db.pets.createIndex({ "$**": 1 });

Това би създало индекс на заместващи знаци за всички полета.

Всъщност, това не е съвсем вярно. По подразбиране индексите с заместващи знаци не се създават в _id поле. За да включите _id поле, ще трябва да го включите в wildcardProjection документ.

Не можете да създадете индекси с заместващи знаци? Проверете тази настройка.

mongod featureCompatibilityVersion трябва да е най-малко 4.2 за създаване на заместващи индекси.

Можете да проверите тази настройка със следния код:

db.adminCommand( 
    { 
        getParameter: 1, 
        featureCompatibilityVersion: 1 
    } 
)

Можете да го настроите с помощта на setFeatureCompatibilityVersion команда:

db.adminCommand( { setFeatureCompatibilityVersion: "4.4" } )

setFeatureCompatibilityVersion командата трябва да се изпълни в admin база данни.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB заявка за връщане само на вграден документ

  2. Не мога да намеря документи, търсещи по ObjectId с помощта на Mongoose

  3. Премахване на дублиращи се записи с MapReduce

  4. Препратки към документ Mongoose с връзка „едно към много“.

  5. Премахнете дубликатите от MongoDB