apachelucene是一套opensource的Search-Engine,搜尋效果比直接使用資料庫條件like還要來的好,而且也不會佔用到資料庫的資源,只需要使用到硬碟的IO,所以可以把搜尋引擎另外做到另一個硬碟,或是放到另一台主機上,單獨成搜尋引擎Server,設計成Multi-Tires架構。
在使用apache lucene時,需要先把資料建立成索引檔,搜尋時則直接取用索引資料,來加快查詢的速度,不同類型的資料可以依需求建立成不同的搜尋索引檔,以下範例是如何建立一組索引檔。
索引檔內容如下圖:
需要使用到的jar classpath為lucene-x.x.x.jar,可由官網下載,此範例使用2.3版本,新版本可能用法會不太一樣,如果需要中文的切詞器,可以找到庖丁解字這個opensource的framework。
原始碼如下:
package testlucene; import java.io.*; import java.util.Date; import org.apache.lucene.document.Document; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Field; import org.apache.lucene.index.IndexWriter; public class LuceneIndex { private IndexWriter writer = null ; public LuceneIndex() { try { //建立index的寫入器 //使用標準的分詞器 //重新建立索引檔,也就是之前的檔案會全數重建 writer = new IndexWriter("d:\\index", new StandardAnalyzer(),true); } catch(Exception e) { } } private Document getDocument(File f)throws IOException{ Document doc = new Document(); FileInputStream is = new FileInputStream(f); Reader reader = new BufferedReader( new InputStreamReader(is)); //取得檔案的reader加入field Field field = new Field("contents",reader); //加入index文件檔裡,無法取得資訊 doc.add(field); //加入資訊,不做分詞,search不到此資訊,但可以取得 doc.add(new Field("path", f.getPath(), Field.Store.YES, Field.Index.UN_TOKENIZED)); return doc; } //把目錄裡的檔案全都加入index裡 public void writeToIndex()throws IOException { File folder = new File(Constants.INDEX_FILE_PATH); if(folder.isDirectory()) { String[] files = folder.list(); for(int i = 0 ; i <files.length ; i++) { File file = new File(folder,files[i]); Document doc = getDocument(file); System.out.println("正在建立索引 : "+file+" "); writer.addDocument(doc); } } } //記得要關閉才會真的寫入檔案喔 public void close()throws IOException { writer.close(); } public static void main(String args[])throws IOException { LuceneIndex indexer = new LuceneIndex(); Date start = new Date(); indexer.writeToIndex(); Date end = new Date(); System.out.println("建立索引用時"+(end.getTime() -start.getTime())+"毫杪"); indexer.close(); } }
如此就可以在d:\index看到索引資料檔。
BS low – rtaionliaty high! Really good answer!