MongoDB
 sql >> Teknologi Basis Data >  >> NoSQL >> MongoDB

MongoDb:cara membuat indeks (komposit) yang tepat untuk data dengan banyak bidang yang dapat dicari

Saya akan mencoba menjelaskan apa yang dimaksud dengan contoh. Indeks berdasarkan B-tree bukanlah sesuatu yang spesifik mongodb. Sebaliknya itu adalah konsep yang agak umum.

Jadi ketika Anda membuat indeks - Anda menunjukkan database cara yang lebih mudah untuk menemukan sesuatu. Tetapi indeks ini disimpan di suatu tempat dengan penunjuk yang menunjuk ke lokasi dokumen asli. Informasi ini dipesan dan Anda mungkin melihatnya sebagai pohon biner yang memiliki properti yang sangat bagus:pencarian dikurangi dari O(n) (pemindaian linier) ke O(log(n)) . Yang jauh lebih cepat karena setiap kali kita memangkas ruang kita menjadi dua (berpotensi kita dapat mengurangi waktu dari 10^6 menjadi 20 pencarian). Misalnya kami memiliki koleksi besar dengan bidang {a : some int, b: 'some other things'} dan jika kita mengindeksnya dengan a, kita berakhir dengan struktur data lain yang diurutkan berdasarkan a . Tampilannya begini (maksud saya ini bukan koleksi lain, ini hanya untuk demonstrasi):

{a : 1, pointer: to the field with a = 1}, // if a is the smallest number in the starting collection
...
{a : 999, pointer: to the field with a = 990} // assuming that 999 is the biggest field

Jadi sekarang kita sedang mencari bidang a =18. Alih-alih pergi satu per satu melalui semua elemen, kita mengambil sesuatu di tengah dan jika lebih besar dari 18, maka kita membagi bagian bawah menjadi dua dan memeriksa elemen di sana . Kami melanjutkan sampai kami akan menemukan a =18. Kemudian kami melihat pointer dan mengetahuinya kami mengekstrak bidang asli.

Situasi dengan indeks majemuk serupa (daripada mengurutkan berdasarkan satu elemen, kita mengurutkan banyak). Misalnya Anda memiliki koleksi:

{ "item": 5, "location": 1, "stock": 3, 'a lot of other fields' }  // was stored at position 5 on the disk
{ "item": 1, "location": 3, "stock": 1, 'a lot of other fields' }  // position 1 on the disk
{ "item": 2, "location": 5, "stock": 7, 'a lot of other fields' }  // position 3 on the disk
... huge amount of other data
{ "item": 1, "location": 1, "stock": 1, 'a lot of other fields' }  // position 9 on the disk
{ "item": 1, "location": 1, "stock": 2, 'a lot of other fields' }  // position 7 on the disk

dan ingin indeks { "item":1, "location":1, "stock":1 }. Tabel pencarian akan terlihat seperti ini (sekali lagi - ini bukan koleksi lain, ini hanya untuk demonstrasi):

{ "item": 1, "location": 1, "stock": 1, pointer = 9 }
{ "item": 1, "location": 1, "stock": 2, pointer = 7 }
{ "item": 1, "location": 3, "stock": 1, pointer = 1 }
{ "item": 2, "location": 5, "stock": 7, pointer = 3 }
.. huge amount of other data (but not necessarily here. If item would be one it would be somewhere next to items 1)
{ "item": 5, "location": 1, "stock": 3, pointer = 5 }

Lihat bahwa di sini semuanya pada dasarnya diurutkan berdasarkan item, kemudian berdasarkan lokasi dan kemudian dengan pointer. Dengan cara yang sama seperti dengan indeks tunggal kita tidak perlu memindai semuanya. Jika kita memiliki query yang mencari item = 2, location = 5 and stock = 7 kita dapat dengan cepat mengidentifikasi dokumen mana dengan item = 2 dan kemudian dengan cara yang sama dengan cepat mengidentifikasi di mana di antara item-item ini item dengan location 5 dan seterusnya.

Dan sekarang bagian yang menarik . Kami juga membuat hanya satu indeks (walaupun ini adalah indeks gabungan, ini masih satu indeks) kami dapat menggunakannya untuk menemukan elemen dengan cepat

  • hanya dengan item . Sungguh yang perlu kita lakukan hanyalah langkah pertama. Jadi tidak ada gunanya membuat indeks lain {location :1} karena sudah tercakup oleh indeks majemuk.
  • kami juga dapat dengan cepat menemukan hanya dengan item and by location (kita hanya perlu 2 langkah).

Keren 1 indeks tetapi membantu kami dalam tiga cara berbeda. Tapi tunggu dulu:bagaimana jika kita ingin mencari berdasarkan item and stock . Oh, sepertinya kita bisa mempercepat kueri ini juga. Kita dapat di log(n) menemukan semua elemen dengan item tertentu dan ... di sini kita harus berhenti - sihir telah selesai. Kita perlu mengulangi semuanya. Tapi masih cukup bagus.

Tapi mungkin itu bisa membantu kami dengan pertanyaan lain. Mari kita lihat kueri berdasarkan location yang sepertinya sudah dipesan. Tetapi jika Anda akan melihatnya - Anda melihat bahwa ini berantakan. Satu di awal dan satu lagi di akhir. Ini tidak dapat membantu Anda sama sekali.

Saya harap ini menjelaskan beberapa hal:

  • mengapa indeks bagus (mengurangi waktu dari O(n) menjadi berpotensi O(log(n)))
  • mengapa indeks gabungan dapat membantu dengan beberapa kueri namun kami belum membuat indeks pada bidang tertentu dan membantu dengan beberapa kueri lainnya.
  • indeks apa yang dicakup oleh indeks majemuk
  • mengapa indeks dapat membahayakan (itu menciptakan struktur data tambahan yang harus dipertahankan)

Dan ini akan memberi tahu hal lain yang valid:indeks bukan peluru perak . Anda tidak dapat mempercepat semua kueri Anda, jadi terdengar konyol untuk berpikir bahwa dengan membuat indeks di semua bidang, SEMUANYA akan menjadi sangat cepat.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. fungsi Azure (simpul) memanggil mongodb selesai tanpa kesalahan tetapi tidak ada yang kembali dari kueri

  2. Menemukan peringatan MongoDB setelah mengonversi set replika menjadi server yang berdiri sendiri

  3. Tidak dapat menggunakan Nested VariableOperators.mapItemsOf di Spring Data MongoDb

  4. Rails g gagal untuk perintah mongoid

  5. Nodejs Mongoose membuat dua model dari koleksi