Mesin pencari Lucene: Bertenaga, fleksibel, dan gratis

Jangan biarkan nomor versi rendah - 0,04 per Agustus 2000 - menipu Anda. Mesin pencari Lucene adalah perangkat pencarian yang kuat, kuat, dan fleksibel, siap untuk menangani banyak masalah pencarian umum. Dan karena sekarang tersedia di bawah lisensi open source LGPL yang lebih fleksibel, harganya (gratis!) Juga tepat.

Doug Cutting, pengembang berpengalaman alat pencarian dan pengambilan teks, menciptakan Lucene. Cutting adalah penulis utama mesin pencari V-Twin (bagian dari upaya sistem operasi Copland Apple) dan saat ini menjadi arsitek senior di Excite. Dia merancang Lucene untuk memudahkan penambahan pengindeksan dan kemampuan penelusuran ke berbagai aplikasi, termasuk:

  • Email yang dapat dicari: Aplikasi email memungkinkan pengguna mencari pesan yang diarsipkan dan menambahkan pesan baru ke indeks saat mereka tiba.
  • Pencarian dokumentasi online: Pembaca dokumentasi - berbasis CD, berbasis Web, atau tertanam di dalam aplikasi - dapat memungkinkan pengguna mencari dokumentasi online atau publikasi yang diarsipkan.
  • Halaman Web yang Dapat Ditelusuri: Browser Web atau server proxy dapat membuat mesin pencari pribadi untuk mengindeks setiap Halaman Web yang telah dikunjungi pengguna, memungkinkan pengguna mengunjungi kembali halaman dengan mudah.
  • Pencarian situs web: Program CGI memungkinkan pengguna mencari Situs Web Anda.
  • Pencarian konten: Aplikasi memungkinkan pengguna mencari dokumen yang disimpan untuk konten tertentu; ini dapat diintegrasikan ke dalam dialog Open Document.
  • Kontrol versi dan manajemen konten: Sistem manajemen dokumen dapat mengindeks dokumen, atau versi dokumen, sehingga dapat dengan mudah diambil.
  • News and wire service feeds: Sebuah server berita atau relai dapat mengindeks artikel saat mereka tiba.

Tentu saja, banyak mesin telusur dapat menjalankan sebagian besar fungsi tersebut, tetapi sedikit alat penelusuran sumber terbuka yang menawarkan kemudahan penggunaan, penerapan cepat, dan fleksibilitas Lucene.

Saya pertama kali menggunakan Lucene saat mengembangkan Eyebrowse, alat berbasis Java open source untuk membuat katalog dan menjelajahi milis. (Lihat Sumber untuk link.) Persyaratan inti untuk Eyebrowse adalah kemampuan pencarian dan pengambilan pesan yang fleksibel. Ini menuntut komponen pengindeksan dan pencarian yang secara efisien akan memperbarui basis indeks saat pesan baru tiba, memungkinkan banyak pengguna untuk mencari dan memperbarui basis indeks secara bersamaan, dan menskalakan ke arsip yang berisi jutaan pesan.

Setiap mesin pencari open source lain yang saya evaluasi, termasuk Swish-E, Glimpse, iSearch, dan libibex, tidak sesuai dengan persyaratan Eyebrowse dalam beberapa hal. Ini akan membuat integrasi bermasalah dan / atau memakan waktu. Dengan Lucene, saya menambahkan pengindeksan dan pencarian ke Eyebrowse dalam waktu kurang dari setengah hari, dari pengunduhan awal hingga kode yang berfungsi sepenuhnya! Ini kurang dari sepersepuluh dari waktu pengembangan yang telah saya anggarkan, dan memberikan hasil yang lebih terintegrasi dan kaya fitur daripada alat pencarian lain yang saya pertimbangkan.

Bagaimana mesin pencari bekerja

Membuat dan memelihara indeks terbalik adalah masalah utama saat membangun mesin pencari kata kunci yang efisien. Untuk mengindeks dokumen, Anda harus memindainya terlebih dahulu untuk menghasilkan daftar postingan. Postingan mendeskripsikan kemunculan sebuah kata dalam sebuah dokumen; mereka umumnya menyertakan kata, ID dokumen, dan mungkin lokasi atau frekuensi kata di dalam dokumen.

Jika Anda menganggap postingan sebagai tupel formulir , sekumpulan dokumen akan menghasilkan daftar postingan yang diurutkan berdasarkan ID dokumen. Tetapi untuk secara efisien menemukan dokumen yang berisi kata-kata tertentu, Anda harus mengurutkan posting berdasarkan kata (atau kata dan dokumen, yang akan membuat pencarian multi kata lebih cepat). Dalam pengertian ini, membangun indeks pencarian pada dasarnya adalah masalah pengurutan. Indeks pencarian adalah daftar posting yang diurutkan berdasarkan kata.

Implementasi yang inovatif

Kebanyakan mesin pencari menggunakan B-tree untuk menjaga indeks; mereka relatif stabil sehubungan dengan penyisipan dan memiliki karakteristik I / O berperilaku baik (pencarian dan penyisipan adalah operasi O (log n)). Lucene mengambil pendekatan yang sedikit berbeda: alih-alih mempertahankan satu indeks, Lucene membangun beberapa segmen indeks dan menggabungkannya secara berkala. Untuk setiap dokumen baru yang diindeks, Lucene membuat segmen indeks baru, tetapi dengan cepat menggabungkan segmen kecil dengan yang lebih besar - ini membuat jumlah total segmen tetap kecil sehingga pencarian tetap cepat. Untuk mengoptimalkan indeks untuk pencarian cepat, Lucene dapat menggabungkan semua segmen menjadi satu, yang berguna untuk indeks yang jarang diperbarui. Untuk mencegah konflik (atau mengunci overhead) antara pembaca indeks dan penulis, Lucene tidak pernah mengubah segmen pada tempatnya, itu hanya membuat segmen baru. Saat menggabungkan segmen,Lucene menulis segmen baru dan menghapus yang lama - setelah pembaca aktif menutupnya. Pendekatan ini berskala baik, menawarkan kepada pengembang fleksibilitas tingkat tinggi dalam menukar kecepatan pengindeksan untuk kecepatan pencarian, dan memiliki karakteristik I / O yang diinginkan untuk penggabungan dan pencarian.

Segmen indeks Lucene terdiri dari beberapa file:

  • Indeks kamus yang berisi satu entri untuk setiap 100 entri dalam kamus
  • Kamus yang berisi satu entri untuk setiap kata unik
  • File posting yang berisi entri untuk setiap posting

Karena Lucene tidak pernah memperbarui segmen di tempatnya, mereka dapat disimpan dalam file datar sebagai ganti pohon B yang rumit. Untuk pengambilan cepat, indeks kamus berisi offset ke dalam file kamus, dan kamus menahan offset ke file postingan. Lucene juga menerapkan berbagai trik untuk mengompresi kamus dan mem-posting file - sehingga mengurangi I / O disk - tanpa menimbulkan overhead CPU yang substansial.

Mengevaluasi mesin pencari

Mesin pencari open source lain yang banyak digunakan termasuk Swish-E, Glimpse, libibex, freeWAIS, dan iSearch. Seperti paket perangkat lunak lainnya, masing-masing dioptimalkan untuk digunakan dalam situasi tertentu; Seringkali sulit untuk menerapkan alat ini di luar domain yang dimaksudkan. Pertimbangkan fitur-fitur berikut saat mengevaluasi mesin pencari:

  • Incremental versus batch indexing: Beberapa mesin pencari hanya mendukung pengindeksan batch; setelah mereka membuat indeks untuk sekumpulan dokumen, menambahkan dokumen baru menjadi sulit tanpa mengindeks ulang semua dokumen. Pengindeksan tambahan memungkinkan penambahan dokumen ke indeks yang ada dengan mudah. Untuk beberapa aplikasi, seperti aplikasi yang menangani umpan data langsung, pengindeksan tambahan sangat penting. Lucene mendukung kedua jenis pengindeksan.
  • Sumber data: Banyak mesin telusur hanya dapat mengindeks file atau Halaman Web. Ini cacat aplikasi di mana data yang diindeks berasal dari database, atau di mana beberapa dokumen virtual ada dalam satu file, seperti arsip ZIP. Lucene mengizinkan pengembang untuk mengirimkan dokumen ke pengindeks melalui a Stringatau an InputStream, yang memungkinkan sumber data diambil dari data. Namun, dengan pendekatan ini, pengembang harus menyediakan pembaca yang sesuai untuk data tersebut.
  • Kontrol pengindeksan: Beberapa mesin telusur dapat secara otomatis merayapi pohon direktori atau Situs Web untuk menemukan dokumen yang akan diindeks. Meskipun hal ini nyaman jika data Anda sudah disimpan dengan cara ini, pengindeks berbasis crawler sering kali memberikan fleksibilitas terbatas untuk aplikasi yang memerlukan kontrol yang sangat cermat atas dokumen yang diindeks. Karena Lucene beroperasi terutama dalam mode inkremental, ini memungkinkan aplikasi menemukan dan mengambil dokumen.
  • Format file: Beberapa mesin telusur hanya dapat mengindeks teks atau dokumen HTML; yang lain mendukung mekanisme filter, yang menawarkan alternatif sederhana untuk pengindeksan dokumen pengolah kata, dokumen SGML, dan format file lainnya. Lucene mendukung mekanisme seperti itu.
  • Penandaan konten: Beberapa mesin telusur memperlakukan dokumen sebagai aliran token tunggal; yang lain mengizinkan spesifikasi beberapa bidang data dalam dokumen, seperti "subjek", "abstrak", "pengarang", dan "isi". Hal ini memungkinkan kueri yang lebih kaya secara semantik seperti "penulis berisi Hamilton DAN badan berisi Konstitusi". Lucene mendukung penandaan konten dengan memperlakukan dokumen sebagai kumpulan bidang, dan mendukung kueri yang menentukan bidang mana yang akan dicari.
  • Pemrosesan kata berhenti: Kata-kata umum, seperti "a," "dan," dan "the," menambah sedikit nilai pada indeks pencarian. Tetapi karena kata-kata ini sangat umum, membuat katalognya akan memberikan kontribusi yang besar pada waktu pengindeksan dan ukuran indeks. Kebanyakan mesin pencari tidak akan mengindeks kata-kata tertentu, yang disebut kata-kata berhenti. Beberapa menggunakan daftar kata berhenti, sementara yang lain memilih kata berhenti secara statistik. Lucene menangani kata-kata henti dengan Analyzermekanisme yang lebih umum , yang akan dijelaskan nanti, dan menyediakan StopAnalyzerkelas, yang menghilangkan kata-kata henti dari aliran input.
  • Stemming: Seringkali, pengguna menginginkan kueri untuk satu kata agar cocok dengan kata lain yang serupa. Misalnya, kueri untuk "jump" mungkin juga harus cocok dengan kata "jumped", "jumper", atau "jumps". Mereduksi sebuah kata menjadi bentuk akarnya disebut stemming . Lucene belum menerapkan stemming, tetapi Anda dapat dengan mudah menambahkan stemmer melalui Analyzerkelas yang lebih canggih .
  • Fitur kueri: Mesin telusur mendukung berbagai fitur kueri. Beberapa mendukung kueri Boolean penuh; yang lain hanya mendukung dan pertanyaan. Beberapa mengembalikan skor "relevansi" dengan setiap klik. Beberapa dapat menangani kueri kedekatan atau kedekatan - "penelusuran diikuti oleh mesin" atau "Knicks dekat Celtics" - yang lainnya hanya dapat menelusuri dengan kata kunci tunggal. Beberapa dapat mencari beberapa indeks sekaligus dan menggabungkan hasilnya untuk memberikan skor relevansi yang berarti. Lucene mendukung berbagai fitur kueri, termasuk semua yang tercantum di atas. Namun, Lucene tidak mendukung Soundex yang berharga, atau kueri "kedengarannya seperti".
  • Concurrency: Dapatkah banyak pengguna mencari indeks pada waktu yang sama? Dapatkah pengguna mencari indeks sementara yang lain memperbaruinya? Lucene memungkinkan pengguna untuk mencari indeks secara transaksional, bahkan jika pengguna lain memperbarui indeks secara bersamaan.
  • Dukungan non-Inggris: Banyak mesin pencari secara implisit berasumsi bahwa bahasa Inggris adalah bahasa target; ini terbukti di area seperti daftar stop-word, algoritme stemming, dan penggunaan kedekatan untuk mencocokkan kueri frase. Karena Lucene memproses aliran input melalui Analyzerkelas yang disediakan oleh pengembang, dimungkinkan untuk melakukan pemfilteran khusus bahasa.

Meskipun tidak lengkap, daftar di atas menawarkan titik awal untuk mengevaluasi mesin pencari untuk proyek tertentu. Beberapa alat pencarian tidak cocok untuk tugas tertentu - memahami persyaratan lamaran Anda dapat membantu Anda memilih alat yang tepat untuk pekerjaan itu.

Menggunakan Lucene

Saya akan mengilustrasikan cara menggunakan Lucene untuk membuat, mengisi, dan mencari indeks. Untuk kejelasan, pernyataan impor dan penanganan pengecualian telah dihilangkan dari program sampel. Dalam ilustrasi ini, saya telah menyimpan indeks pencarian di sistem file (Anda dapat menyimpan indeks di mana saja, misalnya, di memori atau di database). File yang diindeks adalah file teks sederhana. Dengan Lucene, Anda juga dapat dengan mudah mengindeks format dokumen lain dan dokumen yang tidak disimpan dalam file.

Buat indeks

The simple program CreateIndex.java creates an empty index by generating an IndexWriter object and instructing it to build an empty index. In this example, the name of the directory that will store the index is specified on the command line.

public class CreateIndex { // usage: CreateIndex index-directory public static void main(String[] args) throws Exception { String indexPath = args[0]; IndexWriter writer; // An index is created by opening an IndexWriter with the // create argument set to true. writer = new IndexWriter(indexPath, null, true); writer.close(); } } 

Index text documents

IndexFile.java shows how to add documents -- the files named on the command line -- to an index. For each file, IndexFiles creates a Document object, then calls IndexWriter.addDocument to add it to the index. From Lucene's point of view, a Document is a collection of fields that are name-value pairs. A Field can obtain its value from a String, for short fields, or an InputStream, for long fields. Using fields allows you to partition a document into separately searchable and indexable sections, and to associate metadata -- such as name, author, or modification date -- with a document. For example, when storing mail messages, you could put a message's subject, author, date, and body in separate fields, then build semantically richer queries like "subject contains Java AND author contains Gosling." In the code below, we store two fields in each Document: path, to identify the original file path so it can be retrieved later, and body, for the file's contents.

public class IndexFiles { // usage: IndexFiles index-path file . . . public static void main(String[] args) throws Exception { String indexPath = args[0]; IndexWriter writer; writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false); for (int i=1; i