Apache Lucene
حدود یک سال و نیم قبل در مطلبی به معرفی خزندههای وب (Web crawlers)
و آموزش راه اندازی یک خزنده وب ساده به زبان جاوا پرداختم. در طول این
مدت افراد بسیاری در مورد خزندههای وب با من تماس گرفتند و سوالات مختلفی
در مورد این خزندهها داشتند. در این مطلب به معرفی و آموزش Apache Lucene
که به منظور جستجو فایلهای متین استفاده می شود، می پردازم. همچنین در
آینده به بررسی ۳ محصول Hadoop, Apache Solr و Apache Nutch خواهم پرداخت.
Apache Lucene
آپاچی
لوسن کتابخانه ای برای راه اندازی موتورهای جستجوی متن می باشد. این
کتابخانه آزاد بوده و تحت لایسنس Apache Licene 2.0 منتشر می شود. این
کتابخانه به زبان جاوا (Java) نوشته شده و سپس به زبان های Delphi, Perl,
C#, C++, Python, Ruby, و PHP پیاده سازی (پورت) شده است.
این کتابخانه
این امکان را برای شما فراهم می آورد تا هر نوع موتور جستجوی متنی مانند
موتور جستوی وب، لوکال (محلی) ویا فقط ویژه یک وب سایت را ایجاد نمایید. در
نظر داشته باشید که Apache Lucene فقط برای جستجو استفاده میشود و برای
جمعآوری اطلاعات و تحلیل آنها نیاز به ابزارهای دیگری مانند Solr و Nutch
دارید.
برای دریافت این کتابخانه به صفحه دانلود آپاچی لوسن مراجعه نمایید. همچنین می توانید نسخه فعلی (۳.۶.۰) را از آدرس زیر دریافت نمایید:
• دانلود کتابخانه آپاچی لوسن نسخه ۳.۶.۰
استفاده از کتابخانه Apache Lucene
در ادامه مراحل مختلف برای آمادهسازی و انجام جستجو را بررسی کرده و در انتها سورس کامل این کلاس را مشاهده خواهید کرد.
مرحله اول: ایندکس کردن اطلاعات
قبل
از هر چیز شما باید اطلاعاتی را که قصد جستجو در آنها را دارید ایندکس
نمایید. ایندکس کردن اطلاعات فواید زیادی دارد که یکی از مهمترین آنها
مرتبسازی و افزایش سرعت جستجو است.
ایندکس اطلاعات در لوسن توسط دو
کلاس Document و Field صورت می پذیرد. Document سند شما و Field اطلاعات
مرتبط با سند مانند عنوان، محتوا و… است. این وظیفه شماست که اطلاعات خود
از جمله رشتهها، انواع فایلها، اطلاعات ذخیره شده در پایگاه داده و… را
به کلاس Document تبدیل و ایندکس نمایید. در زیر تعامل Index, Document و
Field را مشاهده می کنید:
حدود یک سال و نیم قبل در مطلبی به معرفی خزندههای وب (Web crawlers)
و آموزش راه اندازی یک خزنده وب ساده به زبان جاوا پرداختم. در طول این
مدت افراد بسیاری در مورد خزندههای وب با من تماس گرفتند و سوالات مختلفی
در مورد این خزندهها داشتند. در این مطلب به معرفی و آموزش Apache Lucene
که به منظور جستجو فایلهای متین استفاده می شود، می پردازم. همچنین در
آینده به بررسی ۳ محصول Hadoop, Apache Solr و Apache Nutch خواهم پرداخت.
Apache Lucene
آپاچی
لوسن کتابخانه ای برای راه اندازی موتورهای جستجوی متن می باشد. این
کتابخانه آزاد بوده و تحت لایسنس Apache Licene 2.0 منتشر می شود. این
کتابخانه به زبان جاوا (Java) نوشته شده و سپس به زبان های Delphi, Perl,
C#, C++, Python, Ruby, و PHP پیاده سازی (پورت) شده است.
این کتابخانه
این امکان را برای شما فراهم می آورد تا هر نوع موتور جستجوی متنی مانند
موتور جستوی وب، لوکال (محلی) ویا فقط ویژه یک وب سایت را ایجاد نمایید. در
نظر داشته باشید که Apache Lucene فقط برای جستجو استفاده میشود و برای
جمعآوری اطلاعات و تحلیل آنها نیاز به ابزارهای دیگری مانند Solr و Nutch
دارید.
برای دریافت این کتابخانه به صفحه دانلود آپاچی لوسن مراجعه نمایید. همچنین می توانید نسخه فعلی (۳.۶.۰) را از آدرس زیر دریافت نمایید:
• دانلود کتابخانه آپاچی لوسن نسخه ۳.۶.۰
استفاده از کتابخانه Apache Lucene
در ادامه مراحل مختلف برای آمادهسازی و انجام جستجو را بررسی کرده و در انتها سورس کامل این کلاس را مشاهده خواهید کرد.
مرحله اول: ایندکس کردن اطلاعات
قبل
از هر چیز شما باید اطلاعاتی را که قصد جستجو در آنها را دارید ایندکس
نمایید. ایندکس کردن اطلاعات فواید زیادی دارد که یکی از مهمترین آنها
مرتبسازی و افزایش سرعت جستجو است.
ایندکس اطلاعات در لوسن توسط دو
کلاس Document و Field صورت می پذیرد. Document سند شما و Field اطلاعات
مرتبط با سند مانند عنوان، محتوا و… است. این وظیفه شماست که اطلاعات خود
از جمله رشتهها، انواع فایلها، اطلاعات ذخیره شده در پایگاه داده و… را
به کلاس Document تبدیل و ایندکس نمایید. در زیر تعامل Index, Document و
Field را مشاهده می کنید:
بعد از آماده سازی Document باید توسط کلاس IndexWriter، ایندکس را ذخیره
می کنیم. پارامتر اول در فراخوانی IndexWriter دایکتوری ذخیرهسازی ایندکس
را مشاهده میکند.
با کدهای زیر چند عبارت را در حافظه دسترسی تصادفی (RAM) ذخیره کردیم:
می کنیم. پارامتر اول در فراخوانی IndexWriter دایکتوری ذخیرهسازی ایندکس
را مشاهده میکند.
با کدهای زیر چند عبارت را در حافظه دسترسی تصادفی (RAM) ذخیره کردیم:
کد:
Directory index = new RAMDirectory();IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer); IndexWriter w = new IndexWriter(index, config);addDoc(w, "Lucene in Action");addDoc(w, "Lucene for Dummies");addDoc(w, "Managing Gigabytes");addDoc(w, "The Art of Computer Science");w.close();
متد addDoc رشتهها را به ایندکس اضافه می کند:
مرحله دوم: ایجاد کوئری (Query)
در این برنامه ما عبارت مورد نظر برای جستجو را از ورودی (stdin) دریافت میکنیم:
مرحله سوم: انجام جستجو
در این مرحله کوئری (جستار؟) ساخته شده
را بر روی ایندکس جستجو می کنیم. همچنین از کلاس TopScoreDocCollector برای
بدست آوردن ۱۰ نتیجه مرتبطتر استفاده کرده ایم:
مرحله چهارم: مشاهده نتایج
در انتها نتایج بدست آمده را نمایش میدهیم:
همین!
کلاس HelloLucene
در زیر کلاس HelloLucene را یکجا مشاهده می فرمایید:
منابع
کد:
private static void addDoc(IndexWriter w, String value) throws IOException { Document doc = new Document(); doc.add(new Field("title", value, Field.Store.YES, Field.Index.ANALYZED)); w.addDocument(doc); }}
مرحله دوم: ایجاد کوئری (Query)
در این برنامه ما عبارت مورد نظر برای جستجو را از ورودی (stdin) دریافت میکنیم:
کد:
String querystr = args.length > 0 ? args[0] : "lucene";
Query q = new QueryParser(Version.LUCENE_36, "title", analyzer).parse(querystr);
مرحله سوم: انجام جستجو
در این مرحله کوئری (جستار؟) ساخته شده
را بر روی ایندکس جستجو می کنیم. همچنین از کلاس TopScoreDocCollector برای
بدست آوردن ۱۰ نتیجه مرتبطتر استفاده کرده ایم:
کد:
int hitsPerPage = 10;IndexReader reader = IndexReader.open(index);IndexSearcher searcher = new IndexSearcher(reader);TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);searcher.search(q, collector);ScoreDoc[] hits = collector.topDocs().scoreDocs;
مرحله چهارم: مشاهده نتایج
در انتها نتایج بدست آمده را نمایش میدهیم:
کد:
System.out.println("Found " + hits.length + " hits.");for(int i=0;i<hits.length;++i) { int docId = hits[i].doc; Document d = searcher.doc(docId); System.out.println((i + 1) + ". " + d.get("title"));}
کلاس HelloLucene
در زیر کلاس HelloLucene را یکجا مشاهده می فرمایید:
کد:
import java.io.IOException; import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.IndexReader;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.IndexWriterConfig;import org.apache.lucene.queryParser.ParseException;import org.apache.lucene.queryParser.QueryParser;import org.apache.lucene.search.*;import org.apache.lucene.store.Directory;import org.apache.lucene.store.RAMDirectory;import org.apache.lucene.util.Version; public class HelloLucene { public static void main(String[] args) throws IOException, ParseException { // 0. Specify the analyzer for tokenizing text. // The same analyzer should be used for indexing and searching StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36); // 1. create the index Directory index = new RAMDirectory(); IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_36, analyzer); IndexWriter w = new IndexWriter(index, config); addDoc(w, "Lucene in Action"); addDoc(w, "Lucene for Dummies"); addDoc(w, "Managing Gigabytes"); addDoc(w, "The Art of Computer Science"); w.close(); // 2. query String queryStr = args.length > 0 ? args[0] : "lucene"; // the "title" arg specifies the default field to use // when no field is explicitly specified in the query. Query q = new QueryParser(Version.LUCENE_35, "title", analyzer).parse(queryStr); // 3. search int hitsPerPage = 10; IndexReader reader = IndexReader.open(index); IndexSearcher searcher = new IndexSearcher(reader); TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true); searcher.search(q, collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; // 4. display results System.out.println("Found " + hits.length + " hits."); for (int i = 0; i < hits.length; ++i) { int docId = hits[i].doc; Document d = searcher.doc(docId); System.out.println((i + 1) + ". " + d.get("title")); } // searcher can only be closed when there // is no need to access the documents any more. searcher.close(); } private static void addDoc(IndexWriter w, String value) throws IOException { Document doc = new Document(); doc.add(new Field("title", value, Field.Store.YES, Field.Index.ANALYZED)); w.addDocument(doc); }}
منابع
- Lucene in 5 minutes
- An Introduction to Apache Lucene for Full-Text Search
- How do I use Lucene to index and search text files?
- “Did you mean” feature with Apache Lucene Spell-Checker
- A Short Introduction to Lucene