scud(飛云小俠) http://www.jscud.com 轉載請注明來源/作者
關鍵字:lucene,html parser,全文檢索,IndexReader,Document,Field,IndexWriter,Term,HTMLPAGE
無論是建立索引還是分析內容,都是為了用戶的搜索服務.
在Lucene中,如果需要使用搜索,需要使用Searcher類,這是一個抽象類,它有2個子類:IndexSearcher和MultiSearcher.
IndexSearcher是對一個索引進行搜索,如果你需要對多個索引進行搜索,可以使用MultiSearcher.下面的內容只介紹了IndexSearcher.
搜索涉及到幾個問題:分頁,組合條件,根據(jù)條件過濾,排序等等.
分頁:分頁在記錄列表的地方都會遇到,這里不在贅述,我也實現(xiàn)過一個保存分頁結果和顯示結果的類,用于自己的實際工作,下面也會用到保存分頁結果的類,代碼如下:
package com.jscud.support; /** * 分頁顯示用的參數(shù). * * @author scud(飛云小俠) http://www.jscud.com * */ public class DivPageInfo { //開始記錄數(shù) private int recStart; //結束記錄數(shù) private int recEnd; //總頁數(shù) private int pageCount; //當前頁 private int page; //記錄總數(shù) private int recCount; //每頁記錄數(shù) private int perPageRows; public int getNicePageCount() { return getNicePageNum(pageCount); } //get,set等,不在列出 //...... /** * 得到友好的頁數(shù)數(shù)字,頁數(shù)為0時,返回1. * * @return 得到友好的頁數(shù) */ public static int getNicePageNum(int nPage) { if (nPage == 0) { return 1; } else { return nPage; } } } |
顯示分頁結果的類就需要大家根據(jù)自己使用的框架來具體實現(xiàn)了.我使用的是WebWork.
組合條件:在Lucene中,搜索的條件可以組合的很復雜,相關的類有BooleanQuery, FilteredQuery, MultiTermQuery, PhrasePrefixQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery 等等,從而可以組合出很復雜的條件用于查詢.
另外QueryParser可以根據(jù)用戶輸入的字符串和設定的解析器和字段設置等,可以自動產生新的組合條件用于查詢,例如用戶輸入"john AND black",QueryParser可以自己分析出用戶是需要查詢字段中同時包含"john"和"black"的結果.
過濾條件:有時候根據(jù)具體的用戶需求,有些記錄對于一些用戶是不可見的,此時就要使用過濾器來防止不合法的用戶看到不應該看到的記錄.過濾器同時也可以根據(jù)一些具體的條件來過濾掉一些用戶不想看到的記錄.如果需要實現(xiàn)自己的filter,只要參考QueryFilter,DateFilter實現(xiàn)Filter即可.
排序:有時候,可能需要根據(jù)某個字段進行排序,例如按照時間排序.當然更多的時候是按照搜索結果的符合度進行排序,lucene默認的排序就是按照符合度來進行排序的.
進行搜索的代碼如下,根據(jù)自己的需要進行代碼的修改:
/** * 進行搜索. * * 參數(shù)依次為:搜索內容(支持lucene語法),當前頁,每頁記錄數(shù),分頁信息對象 * */ public static List search(String searchText, int page, int perpage, final DivPageInfo pageinfo) { List docs = new ArrayList(); if(!LuceneSearch.indexExist(indexDir)) { return docs; } Searcher searcher = null; //處理檢索條件 BooleanQuery query = new BooleanQuery(); //分頁檢索 DivPageInfo.divPage(hits.length(), perpage, page, pageinfo); //取出當前頁的記錄 return docs; |
代碼中出現(xiàn)了一個新的類Hits,Hits是lucene的搜索結果集,是lazy load的結果集,只有你真正訪問它,它才去裝載真正的數(shù)據(jù).
代碼中還出現(xiàn)了一個LuceneDocument,這是為了在頁面中顯示而寫的一個輔助類,因為lucene的Document是final的,無法進行擴展,而要顯示時間字段必須要調用DateField中的函數(shù),這樣在頁面中顯示就不太直觀了,所以寫了這個輔助類,代碼如下:
package com.jscud.www.support.search; import java.sql.Timestamp; import java.util.Date; import org.apache.lucene.document.DateField; import org.apache.lucene.document.Document; import org.apache.lucene.document.Field; /** * 對Lucene的Document的封裝,用于顯示目的. * * @author scud(飛云小俠) http://www.jscud.com * */ public class LuceneDocument { private Document doc; public LuceneDocument(Document doc) { this.doc = doc; } public static LuceneDocument getDocument(Document doc) { return new LuceneDocument(doc); } public String getValue(String name) { return doc.get(name); } public Field getField(String name) { return doc.getField(name); } public Timestamp getDateTime(String name) { String value = doc.get(name); return new Timestamp( DateField.stringToTime(value)); } public Date getDate(String name) { String value = doc.get(name); return DateField.stringToDate(value); } } |
使用WebWork對結果集進行了顯示,代碼如下:
" target="_blank" > ( |