Anda dapat menganggap indeks bidang tunggal MongoDB sebagai larik, dengan penunjuk ke lokasi dokumen. Misalnya, jika Anda memiliki koleksi dengan (perhatikan bahwa urutannya sengaja di luar urutan):
[collection]
1: {a:3, b:2}
2: {a:1, b:2}
3: {a:2, b:1}
4: {a:1, b:1}
5: {a:2, b:2}
Indeks kolom tunggal
Sekarang jika Anda melakukannya:
db.collection.createIndex({a:1})
Indeks kira-kira terlihat seperti:
[index a:1]
1: {a:1} --> 2, 4
2: {a:2} --> 3, 5
3: {a:3} --> 1
Perhatikan tiga hal penting:
- Diurutkan berdasarkan
a
naik - Setiap entri menunjuk ke lokasi tempat dokumen yang relevan berada
- Indeks hanya mencatat nilai
a
bidang.b
bidang tidak ada dalam indeks sama sekali
Jadi jika Anda melakukan kueri seperti:
db.collection.find().sort({a:1})
Yang harus dilakukan adalah menjalankan indeks dari atas ke bawah, mengambil dan mengeluarkan dokumen yang ditunjuk oleh entri. Perhatikan bahwa Anda juga dapat menelusuri indeks dari bawah, misalnya:
db.collection.find().sort({a:-1})
dan satu-satunya perbedaan adalah Anda menjalankan indeks secara terbalik.
Karena b
tidak ada dalam indeks sama sekali, Anda tidak dapat menggunakan indeks saat menanyakan apa pun tentang b
.
Indeks gabungan
Dalam indeks gabungan misalnya:
db.collection.createIndex({a:1, b:1})
Artinya Anda ingin mengurutkan berdasarkan a
pertama, lalu urutkan berdasarkan b
. Indeks akan terlihat seperti:
[index a:1, b:1]
1: {a:1, b:1} --> 4
2: {a:1, b:2} --> 2
3: {a:2, b:1} --> 3
4: {a:2, b:2} --> 5
5: {a:3, b:2} --> 1
Perhatikan bahwa:
- Indeks diurutkan dari
a
- Dalam setiap
a
Anda memilikib
yang diurutkan - Anda memiliki 5 entri indeks vs. hanya tiga pada contoh kolom tunggal sebelumnya
Dengan menggunakan indeks ini, Anda dapat melakukan kueri seperti:
db.collection.find({a:2}).sort({b:1})
Itu dapat dengan mudah menemukan di mana a:2
kemudian berjalan indeks ke depan. Mengingat indeks itu, Anda tidak dapat melakukannya :
db.collection.find().sort({b:1})
db.collection.find({b:1})
Di kedua kueri Anda tidak dapat dengan mudah menemukan b
karena itu tersebar di seluruh indeks (yaitu tidak dalam entri yang berdekatan). Bagaimanapun Anda bisa lakukan:
db.collection.find({a:2}).sort({b:-1})
karena pada dasarnya Anda dapat menemukan di mana a:2
adalah, dan berjalan di b
entri mundur.
Sunting :klarifikasi pertanyaan @marcospgp di kolom komentar:
Kemungkinan menggunakan indeks {a:1, b:1}
untuk memenuhi find({a:2}).sort({b:-1})
sebenarnya masuk akal jika Anda melihatnya dari sudut pandang tabel yang diurutkan. Misalnya, indeks {a:1, b:1}
dapat dianggap sebagai:
a | b
--|--
1 | 1
1 | 2
2 | 1
2 | 2
2 | 3
3 | 1
3 | 2
temukan({a:2}).sort({b:1})
Indeks {a:1, b:1}
artinya sort by a, then within each a, sort the b values
. Jika Anda kemudian melakukan find({a:2}).sort({b:1})
, indeks tahu di mana semua a=2
adalah. Dalam blok a=2
. ini , b
akan diurutkan dalam urutan menaik (sesuai dengan spesifikasi indeks), sehingga kueri find({a:2}).sort({b:1})
dapat dipenuhi oleh:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block forward to satisfy
2 | 2 <-- find({a:2}).sort({b:1})
2 | 3 <--
3 | 1
3 | 2
temukan({a:2}).sort({b:-1})
Karena indeks dapat berjalan maju atau mundur, prosedur serupa diikuti, dengan sedikit putaran di akhir:
a | b
--|--
1 | 1
1 | 2
2 | 1 <-- walk this block backward to satisfy
2 | 2 <-- find({a:2}).sort({b:-1})
2 | 3 <--
3 | 1
3 | 2
Fakta bahwa indeks dapat berjalan maju atau mundur adalah poin kunci yang memungkinkan kueri find({a:2}).sort({b:-1})
untuk dapat menggunakan indeks {a:1, b:1}
.
Penjelasan perencana kueri
Anda dapat melihat apa yang direncanakan perencana kueri dengan menggunakan db.collection.explain().find(....)
. Pada dasarnya jika Anda melihat stage
dari COLLSCAN
, tidak ada indeks yang digunakan atau dapat digunakan untuk kueri. Lihat menjelaskan hasil
untuk detail tentang keluaran perintah.