Mengelola pengindeksan di Azure Cosmos DB untuk MongoDB
BERLAKU UNTUK: MongoDB
Azure Cosmos DB for MongoDB memanfaatkan kemampuan manajemen indeks inti Azure Cosmos DB. Artikel ini berfokus pada cara menambahkan indeks menggunakan Azure Cosmos DB untuk MongoDB. Indeks adalah struktur data khusus yang membuat penguerian data Anda secara kira-kira berdasarkan urutan besarnya lebih cepat.
Pengindeksan untuk server MongoDB versi 3.6 dan yang lebih tinggi
Azure Cosmos DB untuk server MongoDB versi 3.6+ secara otomatis mengindeks _id
bidang dan kunci shard (hanya dalam koleksi pecahan). API secara otomatis memberlakukan keunikan bidang _id
per kunci shard.
API untuk MongoDB bertingkah berbeda dari Azure Cosmos DB for NoSQL, yang mengindeks semua bidang secara default.
Memperbarui kebijakan pengindeksan
Sebaiknya edit kebijakan pengindeksan Anda di Data Explorer dalam portal Microsoft Azure. Anda bisa menambahkan indeks bidang tunggal dan kartubebas dari editor kebijakan pengindeksan di Data Explorer:
Catatan
Anda tidak dapat membuat indeks campuran menggunakan editor kebijakan pengindeksan di Data Explorer.
Jenis indeks
Bidang tunggal
Anda dapat membuat indeks pada bidang tunggal apa pun. Susunan urutan indeks bidang tunggal tidak masalah. Perintah berikut membuat indeks pada bidang name
:
db.coll.createIndex({name:1})
Anda dapat membuat indeks bidang tunggal yang sama name
di portal Microsoft Azure:
Satu kueri menggunakan beberapa indeks bidang tunggal jika tersedia. Anda dapat membuat hingga 500 indeks bidang tunggal per koleksi.
Indeks campuran (server MongoDB versi 3.6+)
Di API untuk MongoDB, indeks gabungan diperlukan jika kueri Anda memerlukan kemampuan untuk mengurutkan beberapa bidang sekaligus. Untuk kueri dengan beberapa filter yang tidak perlu diurutkan, buat beberapa indeks bidang tunggal sebagai ganti indeks gabungan untuk menghemat biaya pengindeksan.
Indeks gabungan atau indeks bidang tunggal untuk setiap bidang dalam indeks gabungan menghasilkan performa yang sama untuk pemfilteran dalam kueri.
Indeks majemuk pada bidang berlapis tidak didukung secara default karena keterbatasan dengan array. Jika bidang berlapis Anda tidak berisi array, indeks berfungsi seperti yang dimaksudkan. Jika bidang berlapis Anda berisi array (di mana saja di jalur), nilai tersebut diabaikan dalam indeks.
Sebagai contoh, indeks gabungan yang berisi people.dylan.age
pekerjaan dalam kasus ini karena tidak ada array di jalur:
{
"people": {
"dylan": {
"name": "Dylan",
"age": "25"
},
"reed": {
"name": "Reed",
"age": "30"
}
}
}
Indeks senyawa yang sama ini tidak berfungsi dalam kasus ini karena ada array di jalur:
{
"people": [
{
"name": "Dylan",
"age": "25"
},
{
"name": "Reed",
"age": "30"
}
]
}
Fitur ini dapat diaktifkan untuk akun database Anda dengan mengaktifkan kemampuan 'EnableUniqueCompoundNestedDocs'.
Catatan
Anda tidak dapat membuat indeks gabungan pada array.
Perintah berikut membuat indeks campuran pada bidang name
dan age
:
db.coll.createIndex({name:1,age:1})
Anda dapat menggunakan indeks campuran untuk mengurutkan secara efisien pada beberapa bidang sekaligus, seperti yang diperlihatkan dalam contoh berikut:
db.coll.find().sort({name:1,age:1})
Anda juga dapat menggunakan indeks campuran sebelumnya untuk mengurutkan kueri secara efisien dengan susunan urutan yang berlawanan pada semua bidang. Berikut contohnya:
db.coll.find().sort({name:-1,age:-1})
Namun, urutan jalur dalam indeks campuran harus sama persis dengan kueri. Berikut ini contoh kueri yang akan memerlukan indeks campuran tambahan:
db.coll.find().sort({age:1,name:1})
Index Multikunci
Azure Cosmos DB membuat indeks multikunci untuk mengindeks konten yang disimpan dalam array. Jika Anda mengindeks bidang dengan nilai array, Azure Cosmos DB secara otomatis mengindeks setiap elemen dalam array.
Indeks geospasial
Banyak operator geospasial akan mendapat manfaat dari indeks geospasial. Saat ini, Azure Cosmos DB untuk MongoDB mendukung 2dsphere
indeks. API belum mendukung 2d
indeks.
Berikut ini contoh pembuatan indeks geospasial di location
bidang:
db.coll.createIndex({ location : "2dsphere" })
Indeks teks
Azure Cosmos DB untuk MongoDB saat ini tidak mendukung indeks teks. Untuk kueri pencarian teks pada string, Anda harus menggunakan integrasi Azure AI Search dengan Azure Cosmos DB.
Indeks kartubebas
Anda dapat menggunakan indeks kartubebas untuk mendukung kueri terhadap bidang tidak dikenal. Kita bayangkan Anda memiliki koleksi yang menyimpan data keluarga.
Berikut adalah bagian dari contoh dokumen dalam koleksi tersebut:
"children": [
{
"firstName": "Henriette Thaulow",
"grade": "5"
}
]
Berikut contoh lainnya, kali ini dengan sekumpulan properti yang agak berbeda di children
:
"children": [
{
"familyName": "Merriam",
"givenName": "Jesse",
"pets": [
{ "givenName": "Goofy" },
{ "givenName": "Shadow" }
]
},
{
"familyName": "Merriam",
"givenName": "John",
}
]
Dalam koleksi ini, dokumen dapat memiliki banyak properti yang mungkin berbeda. Jika Anda ingin mengindeks semua data dalam children
array, Anda memiliki dua opsi: membuat indeks terpisah untuk setiap properti individual atau membuat satu indeks kartubebas untuk seluruh children
array.
Membuat indeks kartubebas
Perintah berikut membuat indeks kartubebas pada properti apa pun di dalam children
:
db.coll.createIndex({"children.$**" : 1})
Tidak seperti di MongoDB, indeks kartubebas dapat mendukung beberapa bidang dalam predikat kueri. Di dalam performa kueri tidak akan ada perbedaan jika Anda menggunakan satu indeks kartubebas tunggal alih-alih membuat indeks terpisah untuk setiap properti.
Anda dapat membuat jenis indeks berikut menggunakan sintaks kartubebas:
- Bidang tunggal
- Geospasial
Mengindeks semua properti
Berikut cara membuat indeks kartubebas di semua bidang:
db.coll.createIndex( { "$**" : 1 } )
Anda juga dapat membuat indeks kartubebas menggunakan Data Explorer di portal Microsoft Azure:
Catatan
Jika Anda baru memulai pengembangan, kami sangat menyarankan untuk memulai dengan indeks kartubebas di semua bidang. Langkah ini dapat menyederhanakan pengembangan dan mempermudah pengoptimalan kueri.
Dokumen dengan banyak bidang mungkin memiliki biaya Unit Permintaan (RU) yang tinggi untuk penulisan dan pembaruan. Oleh karena itu, jika Anda memiliki beban kerja tulis yang berat, Anda harus memilih untuk secara individual mengindeks jalur dibandingkan menggunakan indeks kartubebas.
Catatan
Dukungan untuk indeks unik pada koleksi yang ada dengan data, tersedia dalam pratinjau. Fitur ini dapat diaktifkan untuk akun database Anda dengan mengaktifkan kemampuan 'EnableUniqueIndexReIndex'.
Batasan
Indeks kartubebas tidak mendukung jenis atau properti indeks berikut:
- Campuran
- TTL
- Unik
Tidak seperti di MongoDB, di Azure Cosmos DB untuk MongoDB Anda tidak dapat menggunakan indeks kartubebas untuk:
Membuat indeks kartubebas yang menyertakan beberapa bidang tertentu
db.coll.createIndex( { "$**" : 1 }, { "wildcardProjection " : { "children.givenName" : 1, "children.grade" : 1 } } )
Membuat indeks kartubebas yang mengecualikan beberapa bidang tertentu
db.coll.createIndex( { "$**" : 1 }, { "wildcardProjection" : { "children.givenName" : 0, "children.grade" : 0 } } )
Atau, Anda dapat membuat beberapa indeks kartubebas.
Properti indeks
Operasi berikut umum untuk akun yang melayani protokol kabel versi 4.0 dan akun yang melayani versi yang lebih lama. Anda dapat mempelajari selengkapnya tentang indeks yang didukung dan properti terindeks.
Indeks unik
Indeks unik berguna untuk memberlakukan bahwa dua dokumen atau lebih tidak berisi nilai yang sama untuk bidang terindeks.
Perintah berikut membuat indeks unik pada bidang student_id
:
globaldb:PRIMARY> db.coll.createIndex( { "student_id" : 1 }, {unique:true} )
{
"_t" : "CreateIndexesResponse",
"ok" : 1,
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 4
}
Untuk koleksi pecahan, Anda harus menyediakan kunci pecahan (partisi) untuk membuat indeks unik. Dengan kata lain, semua indeks unik pada koleksi pecahan adalah indeks gabungan di mana salah satu bidang adalah kunci shard. Bidang pertama dalam urutan harus berupa kunci shard.
Perintah berikut membuat koleksi pecahan coll
(kunci pecahan adalah university
) dengan indeks unik pada bidang student_id
dan university
:
globaldb:PRIMARY> db.runCommand({shardCollection: db.coll._fullName, key: { university: "hashed"}});
{
"_t" : "ShardCollectionResponse",
"ok" : 1,
"collectionsharded" : "test.coll"
}
globaldb:PRIMARY> db.coll.createIndex( { "university" : 1, "student_id" : 1 }, {unique:true});
{
"_t" : "CreateIndexesResponse",
"ok" : 1,
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4
}
Dalam contoh sebelumnya, menghilangkan "university":1
klausa menampilkan kesalahan dengan pesan berikut:
cannot create unique index over {student_id : 1.0} with shard key pattern { university : 1.0 }
Batasan
Indeks unik perlu dibuat saat koleksi kosong.
Indeks unik pada bidang berlapis tidak didukung secara default karena keterbatasan dengan array. Jika bidang berlapis Anda tidak berisi array, indeks akan berfungsi seperti yang dimaksudkan. Jika bidang berlapis Anda berisi array (di mana saja di jalur), nilai tersebut akan diabaikan dalam indeks unik dan keunikan tidak akan dipertahankan untuk nilai tersebut.
Misalnya indeks unik pada people.tom.age akan berfungsi dalam kasus ini karena tidak ada array di jalur:
{ "people": { "tom": { "age": "25" }, "mark": { "age": "30" } } }
tetapi tidak akan berfungsi dalam kasus ini karena ada array di jalur:
{ "people": { "tom": [ { "age": "25" } ], "mark": [ { "age": "30" } ] } }
Fitur ini dapat diaktifkan untuk akun database Anda dengan mengaktifkan kemampuan 'EnableUniqueCompoundNestedDocs'.
Indeks TTL
Untuk mengaktifkan kedaluwarsa dokumen dalam koleksi tertentu, Anda perlu membuat indeks time-to-live (TTL). Indeks TTL adalah indeks pada _ts
bidang dengan expireAfterSeconds
nilai.
Contoh:
globaldb:PRIMARY> db.coll.createIndex({"_ts":1}, {expireAfterSeconds: 10})
Perintah sebelumnya menghapus dokumen apa pun dalam db.coll
koleksi yang belum dimodifikasi dalam 10 detik terakhir.
Catatan
Bidang _ts khusus untuk Azure Cosmos DB dan tidak dapat diakses dari klien MongoDB. Bidang ini adalah properti (sistem) cadangan yang berisi tanda waktu modifikasi terakhir dokumen.
Lacak progres indeks
Azure Cosmos DB for MongoDB versi 3.6+ mendukung currentOp()
perintah untuk melacak kemajuan indeks pada instans database. Perintah ini menampilkan dokumen yang berisi informasi tentang operasi yang sedang berlangsung pada instans database. Anda menggunakan currentOp
perintah untuk melacak semua operasi yang sedang berlangsung di MongoDB asli. Di Azure Cosmos DB untuk MongoDB, perintah ini hanya mendukung pelacakan operasi indeks.
Berikut adalah beberapa contoh yang memperlihatkan cara menggunakan currentOp
perintah untuk melacak progres indeks:
Dapatkan progres indeks untuk koleksi:
db.currentOp({"command.createIndexes": <collectionName>, "command.$db": <databaseName>})
Dapatkan progres indeks untuk semua koleksi dalam database:
db.currentOp({"command.$db": <databaseName>})
Dapatkan kemajuan indeks untuk semua database dan koleksi di akun Azure Cosmos DB:
db.currentOp({"command.createIndexes": { $exists : true } })
Contoh output progres indeks
Detail progres indeks memperlihatkan persentase progres untuk operasi indeks saat ini. Berikut adalah contoh yang memperlihatkan format dokumen output untuk berbagai tahap progres indeks:
Operasi indeks pada koleksi "foo" dan database "bar" yang 60 persen selesai akan memiliki dokumen output berikut. Bidang
Inprog[0].progress.total
menunjukkan 100 sebagai persentase penyelesaian target.{ "inprog" : [ { ………………... "command" : { "createIndexes" : foo "indexes" :[ ], "$db" : bar }, "msg" : "Index Build (background) Index Build (background): 60 %", "progress" : { "done" : 60, "total" : 100 }, …………..….. } ], "ok" : 1 }
Jika operasi indeks baru saja dimulai pada koleksi "foo" dan database "bar", dokumen output mungkin menunjukkan progres 0 persen hingga mencapai tingkat terukur.
{ "inprog" : [ { ………………... "command" : { "createIndexes" : foo "indexes" :[ ], "$db" : bar }, "msg" : "Index Build (background) Index Build (background): 0 %", "progress" : { "done" : 0, "total" : 100 }, …………..….. } ], "ok" : 1 }
Saat operasi indeks yang sedang berlangsung telah selesai, dokumen output memperlihatkan operasi
inprog
kosong.{ "inprog" : [], "ok" : 1 }
Pembaruan indeks latar belakang
Terlepas dari nilai yang ditentukan untuk properti indeks Latar Belakang, pembaruan indeks selalu dilakukan di latar belakang. Karena pembaruan indeks memakai Unit Permintaan (RUs) pada prioritas yang lebih rendah dibandingkan operasi database lainnya, perubahan indeks tidak akan menyebabkan waktu henti untuk menulis, memperbarui, atau menghapus.
Tidak ada dampak untuk membaca ketersediaan saat menambahkan indeks baru. Kueri hanya akan menggunakan indeks baru setelah transformasi indeks selesai. Selama transformasi indeks, mesin kueri akan terus menggunakan indeks yang ada, sehingga Anda akan mengamati performa baca yang sama selama transformasi pengindeksan dengan apa yang telah Anda amati sebelum memulai perubahan pengindeksan. Saat menambahkan indeks baru, juga tidak ada risiko hasil kueri yang tidak lengkap atau tidak konsisten.
Saat menghapus indeks dan segera menjalankan kueri yang memiliki filter pada indeks yang dihilangkan, hasilnya mungkin tidak konsisten dan tidak lengkap sampai transformasi indeks selesai. Jika Anda menghapus indeks, mesin kueri tidak memberikan hasil yang konsisten atau lengkap saat kueri memfilter indeks yang baru dihilangkan ini. Sebagian besar pengembang tidak menghilangkan indeks dan kemudian langsung mencoba untuk memintanya, sehingga dalam praktiknya, situasi ini tidak mungkin terjadi.
Catatan
Anda dapat melacak progres indeks.
Perintah ReIndex
Perintah reIndex
akan membuat ulang semua indeks pada sebuah koleksi. Dalam beberapa kasus yang jarang terjadi, performa kueri atau masalah indeks lainnya dalam kumpulan Anda dapat diselesaikan dengan menjalankan perintah reIndex
. Jika Anda mengalami masalah dengan pengindeksan, membuat ulang indeks dengan perintah reIndex
adalah pendekatan yang disarankan.
Anda bisa menjalankan reIndex
perintah menggunakan sintaks berikut:
db.runCommand({ reIndex: <collection> })
Anda dapat menggunakan sintaks di bawah untuk memeriksa apakah perintah reIndex
akan meningkatkan performa kueri dalam kumpulan Anda:
db.runCommand({"customAction":"GetCollection",collection:<collection>, showIndexes:true})
Contoh output:
{
"database" : "myDB",
"collection" : "myCollection",
"provisionedThroughput" : 400,
"indexes" : [
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "myDB.myCollection",
"requiresReIndex" : true
},
{
"v" : 1,
"key" : {
"b.$**" : 1
},
"name" : "b.$**_1",
"ns" : "myDB.myCollection",
"requiresReIndex" : true
}
],
"ok" : 1
}
Jika reIndex
akan meningkatkan performa kueri, requiresReIndex akan menjadi true (benar). Jika reIndex
tidak akan meningkatkan performa kueri, properti ini akan dihilangkan.
Melakukan migrasi koleksi dengan indeks
Saat ini, Anda hanya dapat membuat indeks unik saat koleksi tidak berisi dokumen. Alat migrasi MongoDB populer mencoba membuat indeks unik setelah mengimpor data. Untuk menghindari masalah ini, Anda dapat membuat koleksi dan indeks unik secara manual, dan bukan mengizinkan alat migrasi untuk mencoba. (Anda dapat mencapai perilaku ini mongorestore
dengan menggunakan --noIndexRestore
bendera di baris perintah.)
Pengindeksan untuk MongoDB versi 3.2
Fitur dan default pengindeksan yang tersedia berbeda untuk akun Azure Cosmos DB yang kompatibel dengan protokol kawat MongoDB versi 3.2. Anda dapat memeriksa versi akun Anda dan meningkatkan ke versi 3.6.
Jika Anda menggunakan versi 3.2, bagian ini menguraikan perbedaan utama dengan versi 3.6+.
Menghilangkan indeks default (versi 3.2)
Tidak seperti Versi 3.6+ Azure Cosmos DB untuk MongoDB, versi 3.2 mengindeks setiap properti secara default. Anda dapat menggunakan perintah berikut untuk menghilangkan indeks default ini untuk koleksi (coll
):
> db.coll.dropIndexes()
{ "_t" : "DropIndexesResponse", "ok" : 1, "nIndexesWas" : 3 }
Setelah menghilangkan indeks default, Anda dapat menambahkan lebih banyak indeks seperti yang Anda lakukan di versi 3.6+.
Indeks campuran (versi 3.2)
Indeks campuran menyimpan referensi ke beberapa bidang dokumen. Jika Anda ingin membuat indeks campuran, tingkatkan ke versi 3.6 atau 4.0.
Indeks kartubebas (versi 3.2)
Jika Anda ingin membuat indeks kartubebas, tingkatkan ke versi 4.0 atau 3.6.
Langkah berikutnya
- Pengindeksan di Azure Cosmos DB
- Melakukan kedaluwarsa data di Azure Cosmos DB secara otomatis dengan waktu hidup
- Untuk mempelajari tentang hubungan antara partisi dan pengindeksan, lihat artikel cara Mengkueri kontainer Azure Cosmos DB.
- Mencoba melakukan perencanaan kapasitas untuk migrasi ke Azure Cosmos DB? Anda dapat menggunakan informasi tentang kluster database Anda yang ada saat ini untuk membuat perencanaan kapasitas.
- Jika Anda hanya mengetahui jumlah vCore dan server di kluster database yang ada, baca tentang memperkirakan unit permintaan menggunakan vCore atau vCPU
- Jika Anda mengetahui rasio permintaan umum untuk beban kerja database Anda saat ini, baca memperkirakan unit permintaan menggunakan perencana kapasitas Azure Cosmos DB