Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Indeks adalah struktur yang meningkatkan kecepatan pengambilan data dengan mengaktifkan akses cepat ke bidang tertentu dalam koleksi. Artikel ini menjelaskan cara melakukan pengindeksan di berbagai tingkat bersarang dan mengulas pemanfaatan indeks secara efektif.
Skenario pengindeksan
Kami akan mengerjakan contoh skenario dalam konteks JSON sampel yang sudah ditentukan.
{
"_id": "e79b564e-48b1-4f75-990f-e62de2449239",
"car_id":"AZ-9874532",
"car_info": {
"make": "Mustang",
"model": "GT Fastback",
"year": 2024,
"registration": {
"license_plate": "LJX386",
"state": "WV",
"registration_datetime": {
"$date": "2024-01-10T01:16:44.000Z"
},
"expiration_datetime": {
"$date": "2034-01-10T01:16:44.000Z"
}
}
},
"rental_history": [
{
"rental_id": "RT63857499825952",
"customer_id": "CX8716",
"start_date": {
"$date": "2024-02-29T01:16:44.000Z"
},
"end_date": {
"$date": "2024-03-04T16:54:44.000Z"
},
"pickup_location": { "type": "Point", "coordinates": [ -73.97, 40.77 ]
},
"drop_location": { "type": "Point", "coordinates": [ -73.96, 40.78 ]
},
"total_price": 232.56944444444443,
"daily_rent": 50,
"complains": [
{
"complain_id": "CMP638574998259520",
"issue": "Strange odor inside the car.",
"reported_datetime": {
"$date": "2024-03-03T20:11:44.000Z"
},
"reported_medium": "Website",
"resolutions": [
{
"resolution_datetime": {
"$date": "2024-03-03T20:20:44.000Z"
},
"solution": "Inspect for any leftover food, spills, or trash that might be causing the odor. Contact the rental agency.",
"resolved": true
}
]
}
],
"accidents": [
{
"accident_id": "ACC376184",
"date": {
"$date": "2024-03-03T01:47:44.000Z"
},
"description": "Collisions with Soft Barriers: Accidents involving hitting bushes, shrubs, or other soft barriers.",
"repair_cost": 147
}
]
},
{
"rental_id": "RT63857499825954",
"customer_id": "CX1412",
"start_date": {
"$date": "2033-11-18T01:16:44.000Z"
},
"end_date": {
"$date": "2033-11-25T21:11:44.000Z"
},
"pickup_location": { "type": "Point", "coordinates": [ 40, 5 ]
},
"drop_location": { "type": "Point", "coordinates": [ 41, 11 ]
},
"total_price": 305.3645833333333,
"daily_rent": 39,
"complains": [
{
"complain_id": "CMP638574998259540",
"issue": "Unresponsive infotainment system.",
"reported_datetime": {
"$date": "2033-11-19T17:55:44.000Z"
},
"reported_medium": "Agency",
"resolutions": []
}
],
"accidents": null
}
],
"junk": null
}
Mengindeks bidang utama
Azure DocumentDB memungkinkan indeks pada properti akar. Contoh ini memungkinkan pencarian sampleColl dengan car_id.
CarData> db.sampleColl.createIndex({"car_id":1})
Rencana eksekusi memungkinkan peninjauan pemanfaatan indeks yang dibuat pada kolom car_id dengan explain.
CarData> db.sampleColl.find({"car_id":"ZA-XWB804"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_id' : 'ZA-XWB804' } }})",
explainCommandPlanningTimeMillis: 0.156,
explainCommandExecTimeMillis: 37.956,
dataSize: '32 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 8700,
inputStage: {
stage: 'IXSCAN',
indexName: 'car_id_1',
isBitmap: true,
indexFilterSet: [ { '$eq': { car_id: 'ZA-XWB804' } } ],
estimatedTotalKeysExamined: 174
}
}
},
ok: 1
}
Mengindeks properti bersarang
Azure DocumentDB memungkinkan pengindeksan properti dokumen yang disematkan. Contoh membuat indeks di bidang registration_datetime dalam dokumen registrationberlapis .
CarData> db.sampleColl.createIndex({"car_info.registration.registration_datetime":1})
Tinjau rencana eksekusi dengan explain memberikan pemahaman mendalam tentang pemindaian indeks.
CarData> db.sampleColl.find({"car_info.registration.registration_datetime":
{ $gte : new ISODate("2024-05-01")
,$lt: ISODate("2024-05-07")
}
}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.registration.registration_datetime' : { '$gte' : ISODate('2024-05-01T00:00:00Z'), '$lt' : ISODate('2024-05-07T00:00:00Z') } } }})",
explainCommandPlanningTimeMillis: 0.095,
explainCommandExecTimeMillis: 42.703,
dataSize: '4087 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 4350,
inputStage: {
stage: 'IXSCAN',
indexName: 'car_info.registration.registration_datetime_1',
isBitmap: true,
indexFilterSet: [
{
'$range': {
'car_info.registration.registration_datetime': {
min: ISODate("2024-05-01T00:00:00.000Z"),
max: ISODate("2024-05-07T00:00:00.000Z"),
minInclusive: true,
maxInclusive: false
}
}
}
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Mengindeks array di root
Azure DocumentDB memungkinkan pengindeksan properti akar yang didefinisikan sebagai array. Mari kita pertimbangkan sampel json berikut.
{
"_id": ObjectId("58f56170ee9d4bd5e610d644"),
"id": 1,
"num": 001,
"name": "Bulbasaur",
"img": "http://www.serebii.net/pokemongo/pokemon/001.png",
"type": [ 'Grass', 'Poison' ],
"height": '0.71 m',
"weight": '6.9 kg',
"avg_spawns": 69,
"spawn_time": "20:00",
"multipliers": [ 1.58 ],
"weaknesses": [ "Fire", "Ice", "Flying", "Psychic"],
"next_evolution": [ { "num": "002", "name": "Ivysaur" }, { "num": "003", "name": "Venusaur" }]
}
Dalam contoh kami, kami membuat indeks pada weaknesses bidang array dan memeriksa keberadaan semua ketiga nilai Ground, Water & Fire dalam array.
Cosmicworks> db.Pokemon.createIndex({'weaknesses':1})
Cosmicworks> db.Pokemon.find({"weaknesses":
{$all:["Ground","Water","Fire"]}
}
).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'Pokemon', 'filter' : { 'weaknesses' : { '$all' : ['Ground', 'Water', 'Fire'] } } }})",
explainCommandPlanningTimeMillis: 10.161,
explainCommandExecTimeMillis: 21.64,
dataSize: '906 bytes',
queryPlanner: {
namespace: 'Cosmicworks.Pokemon',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 50,
inputStage: {
stage: 'IXSCAN',
indexName: 'weaknesses_1',
isBitmap: true,
indexFilterSet: [
{ '$all': { weaknesses: [ 'Ground', 'Water', 'Fire' ] } }
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Nota
Untuk MongoServerError: Kunci indeks terlalu besar.
Buat permintaan dukungan untuk mengaktifkan pengindeksan latar belakang, diikuti dengan enableLargeIndexKeys
db.runCommand({ createIndexes: "collectionName", indexes: [{ {"index_spec"}], enableLargeIndexKeys: true });
Mengindeks array bersarang
Azure DocumentDB memungkinkan pengindeksan array berlapis. Contoh ini membuat indeks pada bidang resolutions yang ada di dalam array complains.
CarData> db.sampleColl.createIndex({"rental_history.complains.resolutions":1})
Kami meninjau rencana dengan explain untuk mengidentifikasi setiap penyewaan, tanpa memberikan resolusi kepada pelanggan.
CarData> db.sampleColl.find({"rental_history.complains.resolutions":{ $exists: false, $ne: []}}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'rental_history.complains.resolutions' : { '$exists' : false, '$ne' : [] } } }})",
explainCommandPlanningTimeMillis: 0.12,
explainCommandExecTimeMillis: 48.721000000000004,
dataSize: '1747 kB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 1933,
inputStage: {
stage: 'IXSCAN',
indexName: 'rental_history.complains.resolutions_1',
isBitmap: true,
indexFilterSet: [
{
'$exists': { 'rental_history.complains.resolutions': false }
},
{ '$ne': { 'rental_history.complains.resolutions': [] } }
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Mengindeks bidang tertentu dalam array
Azure DocumentDB memungkinkan mengindeks bidang dalam sebuah array. Contoh membuat indeks pada bidang date di dalam larik accidents.
CarData> db.sampleColl.createIndex({"rental_history.accidents.date":1})
Contoh kueri mengevaluasi kecelakaan dalam rentang waktu, memperlihatkan penggunaan indeks yang dibuat pada properti date.
CarData> db.sampleColl.find({"rental_history.accidents.date":
{ $gte : ISODate("2024-05-01")
, $lt : ISODate("2024-05-07")
}
}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'rental_history.accidents.date' : { '$gte' : ISODate('2024-05-01T00:00:00Z'), '$lt' : ISODate('2024-05-07T00:00:00Z') } } }})",
explainCommandPlanningTimeMillis: 19.816,
explainCommandExecTimeMillis: 48.359,
dataSize: '12 MB',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'FETCH',
estimatedTotalKeysExamined: 4350,
inputStage: {
stage: 'IXSCAN',
indexName: 'rental_history.accidents.date_1',
isBitmap: true,
indexFilterSet: [
{
'$range': {
'rental_history.accidents.date': {
min: ISODate("2024-05-01T00:00:00.000Z"),
max: ISODate("2024-05-07T00:00:00.000Z"),
minInclusive: true,
maxInclusive: false
}
}
}
],
estimatedTotalKeysExamined: 2
}
}
},
ok: 1
}
Nota
Saat ini kami meningkatkan dukungan untuk array berlapis. Dalam kasus tepi tertentu, operasi pengindeksan tertentu dapat menyebabkan kesalahan.
Pengindeksan wildcard saat mengecualikan field bersarang
Azure DocumentDB mendukung indeks Wildcard. Contoh ini memungkinkan kita untuk mengecualikan pengindeksan semua bidang berlapis dalam dokumen car_info.
// Excludes all the nested sub-document property
CarData> db.sampleColl.createIndex( {"$**":1}
,{"wildcardProjection":
{ "car_info.make":0
,"car_info.model":0
,"car_info.registration":0
,"car_info.year":0
,"rental_history":0
}
}
)
Rencana eksekusi tidak mendukung kueri yang dilakukan di kolom model, yang dikecualikan saat indeks Wildcard dibuat.
CarData> db.sampleColl.find({"car_info.model":"GT Fastback"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.model' : 'GT Fastback' } }})",
explainCommandPlanningTimeMillis: 10.879,
explainCommandExecTimeMillis: 374.25100000000003,
dataSize: '0 bytes',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'car_info.model': 'GT Fastback' } } ],
estimatedTotalKeysExamined: 8700
}
},
ok: 1
}
Pengindeksan karakter pengganti sambil mengecualikan objek tertanam
Azure DocumentDB mendukung indeks Wildcard. Contoh ini memungkinkan kita untuk mengecualikan objek berlapis dari dokumen.
// Wildcard index excluding nested object
[mongos] CarData> db.sampleColl.createIndex( {"$**":1},
{"wildcardProjection":
{ "car_info":0
,"rental_history":0
}
}
)
Rencana eksekusi menunjukkan tidak ada dukungan untuk kueri yang dilakukan pada bidang berlapis make dalam dokumen car_info.
CarData> db.sampleColl.find({"car_info.make":"Mustang"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'sampleColl', 'filter' : { 'car_info.make' : 'Mustang' } }})",
explainCommandPlanningTimeMillis: 21.271,
explainCommandExecTimeMillis: 337.475,
dataSize: '0 bytes',
queryPlanner: {
namespace: 'CarData.sampleColl',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'car_info.make': 'Mustang' } } ],
estimatedTotalKeysExamined: 8700
}
},
ok: 1
}
Pengindeksan wildcard dengan mengecualikan kolom dengan array berlapis
Contoh indeks wildcard memungkinkan untuk mengecualikan bidang dari array bersarang. Kami menggunakan pokemon koleksi dengan format json disorot secara khusus.
{
{
"_id": ObjectId("58f56170ee9d4bd5e610d644"),
"id": 1,
"num": 001,
"name": "Bulbasaur",
"img": "http://www.serebii.net/pokemongo/pokemon/001.png",
"type": [ 'Grass', 'Poison' ],
"height": '0.71 m',
"weight": '6.9 kg',
"avg_spawns": 69,
"spawn_time": "20:00",
"multipliers": [ 1.58 ],
"weaknesses": [ "Fire", "Ice", "Flying", "Psychic"],
"next_evolution": [ { "num": "002", "name": "Ivysaur" }, { "num": "003", "name": "Venusaur" }]
}
}
Kami membuat indeks pada semua bidang dalam json, kecuali pada bidang num dan name yang berasal dari dalam array.
Cosmicworks> db.Pokemon.createIndex( {"$**":1},
{"wildcardProjection":
{ "id":0
,"name":0
,"multipliers":0
,"next_evolution.num":0
,"next_evolution.name":0
}
}
)
Rencana penjelasan menunjukkan tidak ada indikasi penggunaan indeks saat melakukan kueri pada bidang name dalam array next_evolution.
Cosmicworks> db.Pokemon.find({"next_evolution.name":"Venusaur"}).explain()
{
explainVersion: 2,
command: "db.runCommand({explain: { 'find' : 'Pokemon', 'filter' : { 'next_evolution.name' : 'Venusaur' } }})",
explainCommandPlanningTimeMillis: 0.799,
explainCommandExecTimeMillis: 0.869,
dataSize: '1090 bytes',
queryPlanner: {
namespace: 'Cosmicworks.Pokemon',
winningPlan: {
stage: 'COLLSCAN',
runtimeFilterSet: [ { '$eq': { 'next_evolution.name': 'Venusaur' } } ],
estimatedTotalKeysExamined: 76
}
},
ok: 1
}
Langkah selanjutnya
- Pelajari di sini tentang pengindeksan Wildcard.
- Pelajari tentang mengindeks Praktik terbaik untuk hasil yang paling efisien.
- Pelajari tentang pengindeksan latar belakang
- Pelajari di sini untuk bekerja dengan pengindeksan Teks.