Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. MongoDB

Full-Text Search di MongoDB

Read Time: 15 mins

Indonesian (Bahasa Indonesia) translation by Hasannudin Amin (you can also view the original English article)

MongoDB, salah satu database NoSQL terkemuka, terkenal dengan kinerja yang cepat, skema fleksibel, skalabilitas dan kemampuan pengindeksan yang bagus Inti dari pertunjukan cepat ini adalah MongoDB indeks, yang mendukung eksekusi kueri dengan efisien dengan menghindari pengumpulan penuh scan dan karenanya membatasi jumlah dokumen pencarian MongoDB.

Mulai dari versi 2.4, MongoDB dimulai dengan fitur eksperimental yang mendukung Full-Text Search menggunakan Text Indexes. Fitur ini ada sekarang menjadi bagian integral dari produk (dan bukan lagi fitur eksperimental). Pada artikel ini kita akan mengeksplorasi fungsi full-text search MongoDB langsung dari fundamental.

Jika Anda baru mengenal MongoDB, saya sarankan Anda membaca artikel berikut di Envato Tuts+ yang akan membantu Anda memahami konsep dasar dari MongoDB:

Dasar

Sebelum kita membahasnya, mari kita lihat beberapa latar belakang. Full-text search mengacu pada teknik full-text database lengkap terhadap kriteria pencarian yang ditentukan oleh pengguna. Ini adalah sesuatu yang mirip dengan cara kami mencari konten di Google (atau dalam faktanya aplikasi pencarian lainnya) dengan memasukkan kata kunci / frase string tertentu dan mengembalikan hasil yang relevan diurutkan berdasarkan rangkingnya.

Disini adalah beberapa skenario lagi di mana kita akan melihat full-text search yang terjadi:

  • Pertimbangkan untuk mencari topik favorit Anda di Wiki. Saat Anda memasukkan teks pencarian di Wiki, mesin pencari menampilkan hasil semua artikel yang berhubungan dengan kata kunci / frase yang Anda cari (walaupun kata kunci tersebut digunakan jauh di dalam artikel). Hasil pencarian ini diurutkan berdasarkan relevansi berdasarkan skor yang cocok.
  • Sebagai contoh lain, perhatikan situs jejaring sosial tempat pengguna bisa melakukan pencarian untuk menemukan semua tulisan yang mengandung kata kunci kucing di dalamnya; atau menjadi lebih kompleks, semua tulisan yang memiliki komentar mengandung kata kucing.

Sebelum kita melanjutkan, ada beberapa istilah umum yang terkait dengan full-text search yang harus Anda ketahui. Persyaratan ini berlaku untuk implementasi full-text search (dan bukan spesifik MongoDB).

Stop Word

Stop Words adalah kata-kata yang tidak relevan yang harus disaring dari teks. Misalnya: a, an, the, is, at, which, dll.

Stemming

Stemming adalah proses mengurangi kata-kata pada batangnya. Misalnya: kata-kata seperti berdiri, berdiri, berdiri, dll memiliki basis dasar yang sama.

Scoring

Peringkat relatif untuk mengukur hasil pencarian mana yang paling relevan.

Alternatif untuk Full-Text Search di MongoDB

Sebelum MongoDB mengemukakan konsep indeks teks, kita akan memodelkan data kami untuk mendukung keyword search atau menggunakan regular expression untuk menerapkan fungsi pencarian fungsi pencarian tersebut. Namun, dengan menggunakan salah satu pendekatan ini memiliki keterbatasan sendiri:

  • Pertama, tidak satu pun pendekatan ini mendukung fungsi seperti stemming, stop words, rangking, dll.
  • Menggunakan Menggunakan pencarian kata kunci akan memerlukan pembuatan indeks multi-kunci, yang tidak cukup dibandingkan dengan full-text.
  • Menggunakan regular expression tidak efisien dari sudut pandang kinerja, karena ungkapan ini tidak efektif memanfaatkan indeks.
  • Selain itu, tidak satu pun dari teknik ini dapat digunakan untuk melakukan pencarian frase apapun (seperti mencari 'film yang diluncurkan pada tahun 2015') atau penelusuran berbobot.

Terlepas dari pendekatan ini, untuk aplikasi sentris search yang lebih maju dan kompleks ada solusi alternatif seperti Elastic Search atau SOLR. Tapi menggunakan salah satu dari solusi ini meningkatkan kompleksitas aplikasi arsitektur, karena MongoDB sekarang harus berbicara dengan database eksternal tambahan.

Perhatikan bahwa full-text search MongoDB tidak diusulkan sebagai penggantian lengkap database mesin pencari seperti Elastic, SOLR, dll. Namun, aplikasi ini dapat digunakan secara efektif untuk sebagian besar aplikasi yang dibangun dengan MongoDB hari ini.

Memperkenalkan MongoDB Pencarian Teks

Dengan menggunakan full-text search MongoDB, Anda dapat menentukan indeks teks pada bidang apa pun dalam dokumen yang nilainya berupa string atau array. Saat kami membuat indeks teks di lapangan, MongoDB memberi tokenizes dan memunculkan konten teks bidang yang diindeks, dan membuat indeks sesuai dengan itu.

Untuk memahami hal-hal lebih jauh, marilah kita menyelami beberapa praktek langsung. Saya ingin Anda mengikuti tutorial dengan saya dengan mencoba contoh di mongo shell. Kita pertama-tama akan membuat beberapa data sampel yang akan kita gunakan sepanjang artikel, dan kemudian kami akan melanjutkan untuk membahas konsep utama.

Untuk tujuan artikel ini, pertimbangkan kumpulan messages yang menyimpan dokumen dengan struktur sebagai berikut:

Mari kita masukkan beberapa contoh dokumen menggunakan perintah insert untuk membuat data pengujian kita:

Membuat Indeks Text

Sebuah indeks teks dibuat sangat mirip dengan bagaimana kita membuat indeks reguler, kecuali bahwa ia menentukan kata kunci text daripada menentukan urutan naik / menurun.

Mengindeks Bidang Tunggal

Buat indeks teks pada bidang subject dokumen kita dengan menggunakan kueri berikut:

Untuk menguji indeks teks yang baru dibuat ini di bidang subject, kami akan mencari dokumen menggunakan $text operator. Kami akan mencari semua dokumen yang memiliki kata kunci dogs di bidang subject mereka.

Karena kita menjalankan pencarian teks, kita juga tertarik untuk mendapatkan beberapa statistik tentang seberapa relevan dokumen yang dihasilkan. Untuk tujuan ini, kita akan menggunakan { $meta: "textScore" }, yang memberikan informasi tentang pemrosesan $text operator. Kita juga akan mengurutkan dokumen dengan textScore mereka menggunakan perintah sort. textScore yang lebih tinggi menunjukkan kecocokan yang lebih relevan.

Permintaan di atas mengembalikan dokumen berikut yang berisi kata kunci dogs di bidang subject mereka.

Seperti yang bisa Anda lihat, dokumen pertama memiliki skor 1 (karena kata kunci dog muncul dua kali dalam subjeknya) dibandingkan dengan dokumen kedua dengan skor 0,66. Kueri juga telah memilah dokumen yang dikembalikan dalam urutan skor mereka.

Satu pertanyaan yang mungkin muncul di benak Anda adalah jika kita mencari kata kunci dogs, mengapa mesin pencari menggunakan kata kunci dog (tanpa 's')? Ingat diskusi kami tentang stemming, di mana kata kunci pencarian dikurangi ke basis mereka? Inilah alasan mengapa dogs kata kunci direduksi menjadi dog.

Pengindeksan Beberapa Bidang (Compound Indexing)

Lebih sering daripada tidak, Anda akan menggunakan pencarian teks di berbagai bidang dokumen. Dalam contoh kita, kita akan mengaktifkan pengindeksan teks gabungan pada bidang subject dan content. Silakan jalankan perintah berikut di shell mongo:

Apakah ini bekerja? Tidak!! Membuat indeks teks kedua akan memberi Anda pesan kesalahan yang mengatakan bahwa indeks pencarian teks lengkap sudah ada. Kenapa gitu? Jawabannya adalah bahwa indeks teks hanya memiliki satu indeks teks per koleksi. Oleh karena jika Anda ingin membuat indeks teks lain, Anda harus memasukkan yang sudah ada dan menciptakan yang baru.

Setelah mengeksekusi kueri pembuatan indeks di atas, coba cari semua dokumen dengan kata kunci cat.

Permintaan di atas akan menampilkan dokumen berikut:

Anda dapat melihat bahwa nilai dokumen pertama, yang berisi kata kunci cat di bidang subject dan content, lebih tinggi.

Mengindekskan Seluruh Dokumen (Wildcard Indexing)

Pada contoh terakhir, kita menempatkan indeks gabungan pada bidang subject dan content. Tapi ada skenario di mana Anda ingin konten teks dalam dokumen Anda dapat dicari.

Misalnya, pertimbangkan untuk menyimpan email dalam dokumen MongoDB. Dalam kasus email, semua bidang, termasuk Pengirim, Penerima, Subjek dan Badan, perlu dapat dicari. Dalam skenario seperti itu Anda dapat mengindeks semua bidang string dokumen Anda menggunakan specifier wildcard $**.

Kueri akan berjalan seperti ini (pastikan Anda menghapus indeks yang ada sebelum membuat yang baru):

Kueri ini akan secara otomatis mengatur indeks teks pada setiap bidang string di dokumen kami. Untuk menguji ini, masukkan dokumen baru dengan location bidang baru di dalamnya:

Sekarang jika Anda mencoba pencarian teks dengan kata kunci chicago (query di bawah), maka akan mengembalikan dokumen yang baru saja kita masukkan.

Beberapa hal yang ingin saya fokuskan di sini:

  • Perhatikan bahwa kita tidak secara eksplisit menentukan indeks pada bidang location setelah kita memasukkan dokumen baru. Ini karena kita sudah mendefinisikan indeks teks pada keseluruhan dokumen menggunakan operator $**.
  • Indeks wildcard bisa lambat, terutama dalam skenario dimana data Anda sangat besar. Untuk alasan ini, rencanakan indeks dokumen Anda (alias wildcard indexes) dengan bijak, karena bisa menyebabkan hit kinerja.

Pencarian Tingkat Lanjut

Pencarian Frase

Anda bisa mencari ungkapan seperti "smart birds who love cooking" dengan menggunakan indeks teks. Secara default, pencarian frase membuat pencarian OR pada semua kata kunci yang ditentukan, yaitu akan mencari dokumen yang berisi kata kunci smart, bird, love atau cook.

Kueri ini akan menampilkan dokumen-dokumen berikut:

Jika Anda ingin melakukan pencarian frase yang tepat (logika AND), Anda dapat melakukannya dengan menentukan tanda kutip ganda di teks pencarian.

Kueri ini akan menghasilkan dokumen berikut, yang berisi ungkapan "cook food" bersama:

Pencarian Negasi

Mengawali kata kunci pencarian dengan - (tanda minus) mengecualikan semua dokumen yang mengandung istilah yang dinegasikan. Misalnya, coba cari dokumen yang berisi kata kunci rat namun tidak berisi birds menggunakan kueri berikut:

Melihat di Balik Layar

Salah satu fungsi penting yang tidak saya ungkapkan sampai sekarang adalah bagaimana Anda melihat di balik layar dan melihat bagaimana kata kunci pencarian Anda stemmed, stop word yang diaplikasikan, negasi, dll. $explain untuk diamankan. Anda bisa menjalankan query yang dijelaskan dengan true sebagai parameternya, yang akan memberi Anda statistik terperinci pada eksekusi kueri.

Jika Anda melihat objek queryPlanner yang dikembalikan oleh perintah penjelasan, Anda akan dapat melihat bagaimana MongoDB mengurai string pencarian yang diberikan. Amati bahwa hal itu mengabaikan stop word seperti who, dan stemmed dogs ke dog.

Anda juga dapat melihat istilah yang kita abaikan dari penelusuran dan frasa yang kita gunakan di bagian parsedTextQuery .

Explain query akan sangat berguna saat kita melakukan kueri penelusuran yang lebih rumit dan ingin menganalisisnya.

Penelusuran Teks Tertimbang

Bila kita memiliki indeks pada lebih dari satu bidang dalam dokumen kita, sebagian besar waktu satu bidang akan lebih penting (yaitu lebih berat) daripada yang lain. Misalnya, ketika Anda mencari di sebuah blog, judul blog harus memiliki bobot tertinggi, diikuti oleh konten blog.

Bobot default untuk setiap bidang yang diindeks adalah 1. Untuk menetapkan bobot relatif untuk bidang yang diindeks, Anda dapat memasukkan opsi weights saat menggunakan perintah createIndex .

Mari kita pahami ini dengan sebuah contoh. Jika Anda mencoba mencari kata kunci cook dengan indeks kita saat ini, maka akan menghasilkan dua dokumen, keduanya memiliki skor yang sama.

Sekarang mari kita ubah indeks kita untuk memasukkan bobot; dengan bidang subject memiliki berat 3 terhadap bidang content yang memiliki berat 1.

Coba cari kata kunci cook sekarang, dan Anda akan melihat bahwa dokumen yang berisi kata kunci ini di bidang subject memiliki skor lebih besar (dari 2) daripada yang lain (yang memiliki 0,66).

Partisi Teks Indeks

Seiring data yang tersimpan dalam aplikasi Anda tumbuh, ukuran indeks teks Anda terus berkembang juga. Dengan peningkatan ukuran indeks teks ini, MongoDB harus mencari semua entri yang diindeks setiap kali pencarian teks dilakukan.

Sebagai teknik untuk menjaga pencarian teks Anda tetap efisien dengan indeks yang berkembang, Anda dapat membatasi jumlah entri indeks hasil pindaian dengan menggunakan kondisi kesetaraan dengan pencarian reguler $text. Contoh yang sangat umum dari ini adalah mencari semua tulisan yang dibuat selama tahun / bulan tertentu, atau mencari semua posting dengan kategori / tag tertentu.

Jika Anda mengamati dokumen yang sedang kami tangani, kita memiliki bidang year di dalamnya yang belum pernah kita gunakan. Skenario yang umum adalah mencari pesan dari tahun ke tahun, bersamaan dengan full-text search yang telah kita pelajari.

Untuk ini, kita dapat membuat indeks gabungan yang menentukan sebuah kunci indeks ascending / descending pada year diikuti oleh indeks teks pada bidang subject. Dengan melakukan ini, kita melakukan dua hal penting:

  • Kita secara logis mempartisi seluruh data koleksi menjadi beberapa set yang dipisahkan oleh tahun.
  • Ini akan membatasi pencarian teks untuk memindai dokumen-dokumen yang jatuh di bawah tahun tertentu (atau menyebutnya).

Jatuhkan indeks yang sudah Anda miliki dan buat indeks senyawa baru pada (year, subject):

Sekarang jalankan query berikut untuk mencari semua pesan yang dibuat pada tahun 2015 dan berisi kata kunci cats:

Permintaan akan mengembalikan hanya satu dokumen yang sesuai seperti yang diharapkan. Jika Anda explain kueri ini dan melihat executionStats, Anda akan mendapati bahwa totalDocsExamined untuk kueri ini adalah 1, yang menegaskan bahwa indeks baru kita dapat dimanfaatkan dengan benar dan MongoDB hanya memindai satu dokumen sementara dengan aman mengabaikan semua dokumen lain yang tidak jatuh di bawah tahun 2015

Indeks Teks: Manfaat

Apa Lagi yang Dapat Dilakukan Indeks Teks?

Kita telah menempuh perjalanan panjang dalam artikel ini untuk belajar tentang indeks teks. Ada banyak konsep lain yang dapat Anda eksperimen dengan indeks teks. Tapi karena cakupan artikel ini, kita tidak akan bisa membahasnya secara rinci hari ini. Namun demikian, mari kita lihat secara singkat apa fungsi ini:

  • Indeks teks memberikan dukungan multi bahasa, memungkinkan Anda untuk mencari dalam berbagai bahasa menggunakan operator $language. MongoDB saat ini mendukung sekitar 15 bahasa, termasuk Prancis, Jerman, Rusia, dll.
  • Indeks teks dapat digunakan dalam query pipeline agregasi. Tahap pencocokan dalam pencarian agregat dapat menentukan penggunaan kueri full-text search.
  • Anda dapat menggunakan operator reguler untuk proyeksi, filter, batasan, jenis, dll., Saat bekerja dengan indeks teks.

Pengindeksan Teks MongoDB vs. Database Pencarian Eksternal

Mengingat fakta bahwa full-text search MongoDB bukanlah pengganti lengkap untuk database mesin pencari tradisional yang digunakan bersama MongoDB, dengan menggunakan fungsi MongoDB asli disarankan karena alasan berikut:

  • Seperti yang baru-baru ini dibicarakan terkait MongoDB, cakupan pencarian teks saat ini bekerja dengan baik untuk sebagian besar aplikasi (sekitar 80%) yang dibangun dengan menggunakan MongoDB hari ini.
  • Membangun kemampuan pencarian aplikasi Anda dalam database aplikasi yang sama mengurangi kompleksitas arsitektur aplikasi.
  • Pencarian teks MongoDB bekerja secara real time, tanpa update lag atau batch. Saat Anda memasukkan atau memperbarui dokumen, entri indeks teks akan diperbarui.
  • Pencarian teks diintegrasikan ke dalam fungsi kernel db MongoDB, ini benar-benar konsisten dan bekerja dengan baik bahkan dengan penghancuran dan replikasi.
  • Ini terintegrasi sempurna dengan fitur Mongo yang ada seperti filter, agregasi, pembaruan, dll.

Indeks Teks: Kekurangan

Full-text search merupakan fitur yang relatif baru di MongoDB, ada beberapa fungsi yang memiliki kekurangan saat ini. Saya akan membagi mereka menjadi tiga kategori. Mari kita lihat.

Fungsionalitas yang Hilang Dari Pencarian Teks

  • Indeks Teks saat ini tidak memiliki kemampuan untuk mendukung antarmuka pluggable seperti stemmers, stop words, etc.
  • Mereka saat ini tidak mendukung fitur seperti pencarian berdasarkan sinonim, kata-kata serupa, dll.
  • Mereka tidak menyimpan posisi istilah, yaitu jumlah kata yang digunakan kedua kata kunci tersebut untuk dipisahkan.
  • Anda tidak dapat menentukan urutan untuk ekspresi semacam dari indeks teks.

Batasan di Fungsionalitas Saat Ini

  • Indeks teks majemuk tidak dapat mencakup jenis indeks lainnya, seperti indeks multi-kunci atau indeks geo-spasial. Selain itu, jika indeks teks gabungan Anda menyertakan kunci indeks sebelum kunci indeks teks, semua kueri harus menentukan operator kesetaraan untuk tombol sebelumnya.
  • Ada beberapa batasan khusus kueri. Misalnya, kueri hanya dapat menentukan satu ekspresi $text tunggal, Anda tidak dapat menggunakan $text dengan $nor, Anda tidak dapat menggunakan perintah hint() dengan $text, menggunakan $text dengan $or yang dibutuhkan semua klausa $or Anda untuk diindeks, dll.

Kerugian Kinerja

  • Indeks teks membuat sebuah overhead saat memasukkan dokumen baru. Hal ini pada gilirannya menyentuh throughput penyisipan.
  • Beberapa pertanyaan seperti pencarian frase bisa relatif lambat.

Kesimpulan

Pencarian teks lengkap selalu menjadi salah satu fitur yang paling dituntut dari MongoDB. Pada artikel ini, kita memulai dengan pengenalan full-text search, sebelum beralih ke dasar-dasar pembuatan indeks teks.

Kita kemudian mengeksplorasi pengindeksan compound, pengindeksan wildcard, pencarian frase dan pencarian negasi. Selanjutnya, kita mengeksplorasi beberapa konsep penting seperti menganalisis indeks teks, pencarian tertimbang, dan membagi partisi secara logis. Kita dapat mengharapkan beberapa pembaruan utama pada pembaruan utama pada fungsi ini dalam rilis MongoDB yang akan datang.

Saya Merekomendasikan sebaiknya Anda memberi teks-search untuk dicoba dan berbagi pemikiran Anda. Jika Anda telah menerapkannya di aplikasi Anda, silakan berbagi pengalaman Anda di sini. Akhirnya, jangan ragu untuk memposting pertanyaan, pemikiran dan saran Anda di artikel ini di bagian komentar.

Advertisement
Did you find this post useful?
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.