posts - 40,  comments - 7,  trackbacks - 0
          ?本文主要面向具體使用,適用于已熟悉java編程的lucene初學者。
          1. Lucene的簡介


          1.1 Lucene 歷史


          ????? org.apache.lucene包是純java語言的全文索引檢索工具包。
          ????? Lucene的作者是資深的全文索引/檢索專家,最開始發布在他本人的主頁上,2001年10月貢獻給APACHE,成為APACHE基金jakarta的一個子項目。
          ????? 目前,lucene廣泛用于全文索引/檢索的項目中。
          ????? lucene也被翻譯成C#版本,目前發展為Lucene.Net(不過最近好象有流產的消息)。


          1.2 Lucene 原理


          ?????? lucene的檢索算法屬于索引檢索,即用空間來換取時間,對需要檢索的文件、字符流進行全文索引,在檢索的時候對索引進行快速的檢索,得到檢索位置,這個位置記錄檢索詞出現的文件路徑或者某個關鍵詞。
          ?????? 在使用數據庫的項目中,不使用數據庫進行檢索的原因主要是:數據庫在非精確查詢的時候使用查詢語言“like %keyword%”,對數據庫進行查詢是對所有記錄遍歷,并對字段進行“%keyword%”匹配,在數據庫的數據龐大以及某個字段存儲的數據量龐大的時候,這種遍歷是致命的,它需要對所有的記錄進行匹配查詢。因此,lucene主要適用于文檔集的全文檢索,以及海量數據庫的模糊檢索,特別是對數據庫的xml或者大數據的字符類型。


          2.Lucene的下載和配置


          2.1 Lucene的下載


          ?????? lucene在jakarta項目中的發布主頁:http://jakarta.apache.org/lucene/docs/index.html。以下主要針對windows用戶,其它用戶請在上面的地址中查找相關下載。


          ?????? lucene的.jar包的下載(包括.jar和一個范例demo):
          http://apache.oregonstate.edu/jakarta/lucene/binaries/lucene-1.4-final.zip


          ??????? lucene的源代碼下載:
          http://www.signal42.com/mirrors/apache/jakarta/lucene/source/lucene-1.4-final-src.zip


          ?lucene的api地址:http://jakarta.apache.org/lucene/docs/api/index.html


          ?本文使用lucene版本:lucene-1.4-final.jar。


          2.2 lucene的配置


          ??????? 首先請確定你的機子已經進行了java使用環境的基本配置,即確保在某個平臺下能夠運行java源代碼,否則請查閱相關文檔進行配置。
          ??????? 接下來進入lucene的配置:
          ??????? 普通使用者:在環境變量的CLASSPATH中添加lucene的位置。比如:“D:\java \lucene-1.4-final\lucene-1.4-final.jar;”。
          ?????? jbuilder使用者:在“Project”--“Project Properties”--“Required Libraries”進行添加。
          ?????? Jsp使用者:也可以直接將lucene-1.4-final.jar文件放到\WEB-INF\classes下。


          3. Lucene 的范例(Demo )


          3.1 Demo說明

          ?????
          ??????? 可以得到的Demo包括:lucene-demos-1.4-final、XMLIndexingDemo,lucene-demos-1.4-final中包括對普通文件和html文件的兩種索引,XMLIndexingDemo針對xml文件的索引。他們的區別主要在于:對普通文件進行索引時只要對文件的全文進行索引,而針對html、xml文件時,對標簽類型不能進行索引,在實現上:html、xml的索引需要額外的數據流分析器,以分析哪些內容有用哪些無用。因此,在后兩者實現上,索引的時間額外開支,甚至超過索引本身時間,而檢索時間沒有區別。


          ??????? 以上Demo中,lucene-demos-1.4-final自帶于lucene-1.4-final.zip中,XMLIndexingDemo的下載地址:
          http://cvs.apache.org/viewcvs.cgi/jakarta-lucene-sandbox/contributions/XML-Indexing-Demo/


          3.2 Demo的運行


          ????????首先將demo.jar的路徑添加如環境變量的CLASSPATH中,例如:“D:\java\lucene-1.4-final\lucene-demos-1.4-final.jar;”,同時確保已經添加lucene-1.4-final.jar。


          ????????然后進行文件的全文索引,在dos控制臺中,輸入命令“java org.apache.lucene.demo.IndexFiles {full-path-to-lucene}/src”,后面的路徑為所要進行索引的文件夾,例如:“java org.apache.lucene.demo.IndexFiles c:\test”。


          ??????? 接著對索引進行檢索,敲入“java org.apache.lucene.demo.SearchFiles”,在提示“Query:”后輸入檢索詞,程序將進行檢索列出檢索得到的結果(檢索詞出現的文件路徑)。
          ?
          ?????? 其他Demo的運行請參考\docs\demo.html。
          ?????? 在運行Demo后請閱讀Demo的源代碼以便深入學習。

          4. 利用Lucene進行索引


          ??????? 進行lucene的熟悉后,我們將學習如何使用Lucene。
          ?一段索引的應用實例:

          ??? //需要捕捉IOException異常
          ??? //建立一個IndexWriter,索引保存目錄為“index”
          ??? String[] stopStrs = {
          ??????? "他奶奶的", "fuck"};
          ??? StandardAnalyzer analyzer = new StandardAnalyzer(stopStrs);
          ??? IndexWriter writer = new IndexWriter("index", analyzer, true);
          ???
          ??? //添加一條文檔
          ??? Document doc = new Document();
          ??? doc.add(Field.UnIndexed("id", "1"));//“id”為字段名,“1”為字段值
          ??? doc.add(Field.Text("text", "fuck,他奶奶的,入門與使用"));
          ??? writer.addDocument(doc);
          ???
          ??? //索引完成后的處理
          ??? writer.optimize();
          ??? writer.close();

          ?????? 看完這段實例后,我們開始熟悉lucene的使用:

          4.1 Lucene的索引接口


          ?在學習索引的時候,首先需要熟悉幾個接口:


          4.1.1分析器Analyzer


          ??????? 分析器主要工作是篩選,一段文檔進來以后,經過它,出去的時候只剩下那些有用的部分,其他則剔除。而這個分析器也可以自己根據需要而編寫。
          ??????? org.apache.lucene.analysis.Analyzer:這是一個虛構類,以下兩個借口均繼承它而來。


          ????????org.apache.lucene.analysis.SimpleAnalyzer:分析器,支持最簡單拉丁語言。


          ????????org.apache.lucene.analysis.standard.StandardAnalyzer:標準分析器,除了拉丁語言還支持亞洲語言,并在一些匹配功能上進行完善。在這個接口中還有一個很重要的構造函數:StandardAnalyzer(String[] stopWords),可以對分析器定義一些使用詞語,這不僅可以免除檢索一些無用信息,而且還可以在檢索中定義禁止的政治性、非法性的檢索關鍵詞。


          4.1.2 IndexWriter


          ????????IndexWriter的構造函數有三種接口,針對目錄Directory、文件File、文件路徑String三種情況。
          例如IndexWriter(String path, Analyzer a, boolean create),path為文件路徑,a為分析器,create標志是否重建索引(true:建立或者覆蓋已存在的索引,false:擴展已存在的索引。)
          ?????? 一些重要的方法:

          接口名

          備注

          addDocument(Document doc)

          索引添加一個文檔

          addIndexes(Directory[] dirs)

          將目錄中已存在索引添加到這個索引

          addIndexes(IndexReader[] readers)

          將提供的索引添加到這個索引

          optimize()

          合并索引并優化

          close()

          關閉


          ?????? IndexWriter為了減少大量的io維護操作,在每得到一定量的索引后建立新的小索引文件(筆者測試索引批量的最小單位為10),然后再定期將它們整合到一個索引文件中,因此在索引結束時必須進行wirter. optimize(),以便將所有索引合并優化。


          4.1.3 org.apache.lucene.document


          ?以下介紹兩種主要的類:
          ?a)org.apache.lucene.document.Document:
          ????????Document文檔類似數據庫中的一條記錄,可以由好幾個字段(Field)組成,并且字段可以套用不同的類型(詳細見b)。Document的幾種接口:
          ?

          接口名

          備注

          add(Field field)

          添加一個字段(Field)到Document

          String get(String name)

          從文檔中獲得一個字段對應的文本

          Field getField(String name)

          由字段名獲得字段值

          Field[] getFields(String name)

          由字段名獲得字段值的集


          ?b)org.apache.lucene.document.Field
          ??????? 即上文所說的“字段”,它是Document的片段section。
          ??????? Field的構造函數:
          ?????? Field(String name, String string, boolean store, boolean index, boolean token)。
          ??????? Indexed:如果字段是Indexed的,表示這個字段是可檢索的。
          ????????Stored:如果字段是Stored的,表示這個字段的值可以從檢索結果中得到。
          ????????Tokenized:如果一個字段是Tokenized的,表示它是有經過Analyzer轉變后成為一個tokens序列,在這個轉變過程tokenization中,Analyzer提取出需要進行索引的文本,而剔除一些冗余的詞句(例如:a,the,they等,詳見org.apache.lucene.analysis.StopAnalyzer.ENGLISH_STOP_WORDS和org.apache.lucene.analysis.standard.StandardAnalyzer(String[] stopWords)的API)。Token是索引時候的基本單元,代表一個被索引的詞,例如一個英文單詞,或者一個漢字。因此,所有包含中文的文本都必須是Tokenized的。
          ???? Field的幾種接口:

          Name

          Stored

          Indexed

          Tokenized

          use

          Keyword(String name,

          ??????? String value)

          Y

          Y

          N

          date,url

          Text(String name, Reader value)

          N

          Y

          Y

          short text fields:

          title,subject

          Text(String name, String value)

          Y

          Y

          Y

          longer text fields,

          like “body”

          UnIndexed(String name,

          String value)

          Y

          N

          N

          ?

          UnStored(String name,

          ???????? String value)

          N

          Y

          Y

          ?

          ?


          5. 利用Lucene進行檢索


          5.1 一段簡單的檢索代碼

          ?

          ??? //需要捕捉IOException,ParseException異常
          ??? //處理檢索條件
          ??? Query query = QueryParser.parse("入門", "text", analyzer);

          ??? //檢索
          ??? Searcher searcher = new IndexSearcher("./index");//"index"指定索引文件位置
          Hits hits = searcher.search(query);

          ??? //打印結果值集
          ??? for (int i = 0; i < hits.length(); i++) {
          ????? doc = hits.doc(i);
          ????? String id = doc.get("id");
          ????? System.out.println("found " + "入門" + " on the id:" + id);
          }

          ?

          5.2 利用Lucene的檢索接口


          5.2.1 Query與QueryParser


          ??????? 主要使用方法:
          QueryParser .parse(String query, String field, Analyzer analyzer),例如:
          Query query = QueryParser.parse("入門", "text", analyzer);
          "入門"為檢索詞, "text"為檢索的字段名, analyzer為分析器


          5.2.2 Hits與Searcher


          ?????? Hits的主要使用接口:
          ?

          接口名

          備注

          Doc(int n)

          返回第n個的文檔的所有字段

          length()

          返回這個集中的可用個數

          ?


          6. Lucene的其他使用


          6.1 Lucene 的索引修改


          ??????? 下面給出一段修改索引的代碼,請根據Lucene的API解讀:


          ? /**
          ?? * 對已有的索引添加新的一條索引
          ?? * @param idStr String:要修改的id
          ?? * @param doc Document:要修改的值
          ?? */
          ? public void addIndex(String idStr, String valueStr) {
          ??? StandardAnalyzer analyzer = new StandardAnalyzer();
          ??? IndexWriter writer = null;
          ??? try {
          ????? writer = new IndexWriter(indexPath, analyzer, false);
          ????? writer.mergeFactor = 2; //修正lucene 1.4.2 bug,不添加則不合并原有索引

          ?????? ?? Document doc = new Document();
          ????????? doc.add(Field.UnIndexed("id", idStr));//“id”為字段名,“1”為字段值
          ????????? doc.add(Field.Text("text", valueStr));
          ????? writer.addDocument(doc);

          ????? writer.optimize();
          ????? writer.close();
          ??? }
          ??? catch (IOException ioe) {
          ????? ioe.printStackTrace();
          ??? }
          ? }

          ? /**
          ?? * 刪除索引
          ?? *
          ?? * @param idStr String
          ?? */
          ? public void deleteIndex(String idStr) {
          ??? try {
          ????? Directory dirt = FSDirectory.getDirectory(indexPath, false);
          ????? IndexReader reader = IndexReader.open(dirt);
          ????? IndexXML.deleteIndex(idStr, reader);
          ????? reader.close();
          ????? dirt.close();
          ??? }
          ??? catch (IOException ioe) {
          ????? ioe.printStackTrace();
          ??? }
          ? }


          6.2 Lucene 的檢索結果排序


          ??????? Lucene的排序主要是對org.apache.lucene.search.Sort的使用。Sort可以直接根據字段Field生成,也可以根據標準的SortField生成,但是作為Sort的字段,必須符合以下的條件:唯一值以及Indexed。可以對Integers, Floats, Strings三種類型排序。
          ??????? 對整數型的ID檢索結果排序只要進行以下的簡單操作:

          ?Sort sort = new Sort("id");
          Hits hits = searcher.search(query, sort);

          ?????? 用戶還可以根據自己定義更加復雜的排序,詳細請參考API。


          7 總結


          ??????? Lucene給java的全文索引檢索帶來了非常強大的力量,以上僅對Lucene進行簡單的入門說明。

          posted on 2006-11-08 14:59 Lansing 閱讀(349) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2006年11月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          歡迎探討,努力學習Java哈

          常用鏈接

          留言簿(3)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          Lansing's Download

          Lansing's Link

          我的博客

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 仙游县| 溆浦县| 白朗县| 三门峡市| 洪洞县| 金溪县| 烟台市| 淳化县| 达孜县| 班玛县| 贵南县| 桐梓县| 通榆县| 淳化县| 龙江县| 元朗区| 涟水县| 保山市| 金门县| 甘孜| 龙山县| 尼勒克县| 依安县| 清流县| 威海市| 兴山县| 稻城县| 墨玉县| 普陀区| 武夷山市| 类乌齐县| 波密县| 丹棱县| 镇安县| 贵南县| 南部县| 金门县| 伊吾县| 弋阳县| 六安市| 收藏|