2010年2月5日 星期五

[Lucene]全文檢索

把AP的lucene版本從1.9.0升級到3.0.0(以下的舊版指1.9.0,新版指3.0.0)
發現一些舊的寫法(物件)在新版已不沿用了
還好在架構上並沒有太大的變動
所以也沒改到太多東西
就利用這邊來簡單紀錄一下

我認為的Lucene精神還是分做兩部份
建立索引和查詢索引

建立索引
IndexWriter的建構子已跟舊版不同
利用String或File傳入目錄路徑已不適用
新版以Directory類做為參數
FSDirectory,它表示一個存儲在文件系統中的索引的位置。
RAMDirectory,它表示一個存儲在內存當中的索引的位置。

FSDirectory FSDir = FSDirectory.open(fPath);
Analyzer standardAnalyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
IndexWriter writer = new IndexWriter(FSDir, standardAnalyzer, true, IndexWriter.MaxFieldLength.UNLIMITED);
產生Document並加入Field
其中Field.Index的屬性與舊版有些不同
原有的Field.Index.UN_TOKENIZED和Field.Index.TOKENIZED
已取代成Field.Index.ANALYZED和Field.Index.NOT_ANALYZED
Document doc = doc = new Document();
doc.add(new Field("id", id, Field.Store.YES, Field.Index.ANALYZED));
IndexWriter加入document
writer.addDocument(doc);
writer.optimize();
writer.commit();
writer.close();
查詢索引
IndexSearcher searcher = new IndexSearcher(FSDir, true);
String[] field = {"id"};
Analyzer standardAnalyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
MultiFieldQueryParser mfqp = new MultiFieldQueryParser(Version.LUCENE_CURRENT, field, standardAnalyzer);
Query query = mfqp.parse(sQuery);
TopDocs td = searcher.search(query, 1000);
int totalHits = td.totalHits;
ScoreDoc[] hits = td.scoreDocs;
for (int i = 0; i < hits.length; i++) {
Document doc = searcher.doc(hits[i].doc);
}

這部份差別比較大的地方是新版已無Hits類別
舊版的寫法為
Hits hits = searcher.search(query);
for (int i = 0; i < hits.length(); i++) {
Document doc = hits.doc(i);
}
更新版本後
發現新版在建立索引時
比舊版快了非常多
以約50000筆的資料來比
舊版花了一兩分鐘
新版只用5,6秒
看來花時間更新是有價值的!