Когато създавате заместващ индекс в 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), така че както се очакваше, не използва индекса.