Saat Anda membuat indeks wildcard di MongoDB, Anda memiliki opsi untuk menentukan satu bidang, semua bidang, atau hanya beberapa.
Anda juga memiliki opsi untuk mengecualikan bidang tertentu. Dengan kata lain, Anda dapat menentukan semua bidang kecuali untuk satu atau beberapa bidang tertentu.
Anda dapat menggunakan wildcardProjection
parameter untuk menyertakan atau mengecualikan jalur bidang tertentu dari indeks karakter pengganti. Artikel ini menyajikan contoh mengecualikan bidang tertentu dalam indeks karakter pengganti.
Contoh Dokumen
Misalkan kita memiliki koleksi yang disebut pets
dengan dokumen sebagai berikut:
{ "_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") } }
Kita bisa membuat indeks wildcard di seluruh koleksi, sementara mengecualikan bidang tertentu.
Buat Indeks
Ini contohnya:
db.pets.createIndex(
{ "$**" : 1 },
{
"wildcardProjection" : {
"details.awards" : 0,
"details.eats" : 0
}
}
)
Keluaran:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
{ "$**" : 1 }
bagian inilah yang membuat indeks wildcard, dan wildcardProjection
bagian adalah bagian yang menentukan bidang mana yang akan dikecualikan. Dalam hal ini kami telah mengecualikan details.awards
dan details.eats
bidang. Memberi mereka nilai 0
secara eksplisit mengecualikan mereka dari indeks.
Melihat Indeks
Kita dapat melihat indeks pada koleksi dengan memanggil getIndexes()
cara:
db.pets.getIndexes()
Hasil:
[ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "$**" : 1 }, "name" : "$**_1", "wildcardProjection" : { "details.awards" : 0, "details.eats" : 0 } } ]
Kita dapat melihat bahwa ada dua indeks.
- Indeks pertama ada di
_id
bidang. Ini dibuat saat koleksi dibuat (MongoDB membuat indeks unik di bidang _id selama pembuatan koleksi). - Indeks kedua adalah indeks wildcard kami. Kita dapat melihat bahwa itu secara otomatis bernama
$**_1
, dan itu mencakup bidang yang kami tentukan bersama dengan nilai0
, yang berarti mereka secara eksplisit dikecualikan dari indeks.
Uji Indeks
Kami juga dapat menjalankan beberapa kueri untuk melihat apakah indeks kami akan digunakan, dan apakah bidang yang dikecualikan benar-benar akan dikecualikan
Kueri berikut harus menggunakan indeks:
db.pets.find( { "details.type" : "Dog" } )
Itu harus menggunakan indeks karena kami tidak mengecualikan details.type
bidang dari indeks.
Untuk menguji ini, kita dapat menambahkan explain()
metode untuk melihat rencana kueri:
db.pets.find( { "details.type" : "Dog" } ).explain()
Hasil:
{ "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 }
Kami dapat melihat bahwa itu menggunakan pemindaian indeks (IXSCAN) pada indeks kami.
Berbeda dengan ini, inilah yang terjadi saat kami menjalankan kueri di salah satu bidang yang kecualikan dari indeks:
db.pets.find( { "details.awards.Florida Dog Awards" : "Top Dog" } ).explain()
Hasil:
{ "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 }
Dalam hal ini ia melakukan pemindaian koleksi (COLLSCAN), sehingga seperti yang diharapkan, ia tidak menggunakan indeks.