馬光軍--------BLOG

          BlogJava 聯(lián)系 聚合 管理
            1 Posts :: 25 Stories :: 5 Comments :: 0 Trackbacks

          Lucene 軟件包的發(fā)布形式是一個(gè) JAR 文件,下面我們分析一下這個(gè) JAR 文件里面的主要的 JAVA 包,使讀者對(duì)之有個(gè)初步的了解。

          Package: org.apache.lucene.document

          這個(gè)包提供了一些為封裝要索引的文檔所需要的類(lèi),比如 Document, Field。這樣,每一個(gè)文檔最終被封裝成了一個(gè) Document 對(duì)象。

          Package: org.apache.lucene.analysis

          這個(gè)包主要功能是對(duì)文檔進(jìn)行分詞,因?yàn)槲臋n在建立索引之前必須要進(jìn)行分詞,所以這個(gè)包的作用可以看成是為建立索引做準(zhǔn)備工作。

          Package: org.apache.lucene.index

          這個(gè)包提供了一些類(lèi)來(lái)協(xié)助創(chuàng)建索引以及對(duì)創(chuàng)建好的索引進(jìn)行更新。這里面有兩個(gè)基礎(chǔ)的類(lèi):IndexWriter 和 IndexReader,其中 IndexWriter 是用來(lái)創(chuàng)建索引并添加文檔到索引中的,IndexReader 是用來(lái)刪除索引中的文檔的。

          Package: org.apache.lucene.search

          這個(gè)包提供了對(duì)在建立好的索引上進(jìn)行搜索所需要的類(lèi)。比如 IndexSearcher 和 Hits, IndexSearcher 定義了在指定的索引上進(jìn)行搜索的方法,Hits 用來(lái)保存搜索得到的結(jié)果。

          建立索引

          為了對(duì)文檔進(jìn)行索引,Lucene 提供了五個(gè)基礎(chǔ)的類(lèi),他們分別是 Document, Field, IndexWriter, Analyzer, Directory。下面我們分別介紹一下這五個(gè)類(lèi)的用途:

          Document

          Document 是用來(lái)描述文檔的,這里的文檔可以指一個(gè) HTML 頁(yè)面,一封電子郵件,或者是一個(gè)文本文件。一個(gè) Document 對(duì)象由多個(gè) Field 對(duì)象組成的。可以把一個(gè) Document 對(duì)象想象成數(shù)據(jù)庫(kù)中的一個(gè)記錄,而每個(gè) Field 對(duì)象就是記錄的一個(gè)字段。

          Field

          Field 對(duì)象是用來(lái)描述一個(gè)文檔的某個(gè)屬性的,比如一封電子郵件的標(biāo)題和內(nèi)容可以用兩個(gè) Field 對(duì)象分別描述。

          Analyzer

          在一個(gè)文檔被索引之前,首先需要對(duì)文檔內(nèi)容進(jìn)行分詞處理,這部分工作就是由 Analyzer 來(lái)做的。Analyzer 類(lèi)是一個(gè)抽象類(lèi),它有多個(gè)實(shí)現(xiàn)。針對(duì)不同的語(yǔ)言和應(yīng)用需要選擇適合的 Analyzer。Analyzer 把分詞后的內(nèi)容交給 IndexWriter 來(lái)建立索引。

          IndexWriter

          IndexWriter 是 Lucene 用來(lái)創(chuàng)建索引的一個(gè)核心的類(lèi),他的作用是把一個(gè)個(gè)的 Document 對(duì)象加到索引中來(lái)。

          Directory

          這個(gè)類(lèi)代表了 Lucene 的索引的存儲(chǔ)的位置,這是一個(gè)抽象類(lèi),它目前有兩個(gè)實(shí)現(xiàn),第一個(gè)是 FSDirectory,它表示一個(gè)存儲(chǔ)在文件系統(tǒng)中的索引的位置。第二個(gè)是 RAMDirectory,它表示一個(gè)存儲(chǔ)在內(nèi)存當(dāng)中的索引的位置。

          熟悉了建立索引所需要的這些類(lèi)后,我們就開(kāi)始對(duì)某個(gè)目錄下面的文本文件建立索引了,清單1給出了對(duì)某個(gè)目錄下的文本文件建立索引的源代碼。

          清單 1. 對(duì)文本文件建立索引
          package TestLucene;
                      import java.io.File;
                      import java.io.FileReader;
                      import java.io.Reader;
                      import java.util.Date;
                      import org.apache.lucene.analysis.Analyzer;
                      import org.apache.lucene.analysis.standard.StandardAnalyzer;
                      import org.apache.lucene.document.Document;
                      import org.apache.lucene.document.Field;
                      import org.apache.lucene.index.IndexWriter;
                      /**
                      * This class demonstrate the process of creating index with Lucene
                      * for text files
                      */
                      public class TxtFileIndexer {
                      public static void main(String[] args) throws Exception{
                      //indexDir is the directory that hosts Lucene's index files
                      File   indexDir = new File("D:\\luceneIndex");
                      //dataDir is the directory that hosts the text files that to be indexed
                      File   dataDir  = new File("D:\\luceneData");
                      Analyzer luceneAnalyzer = new StandardAnalyzer();
                      File[] dataFiles  = dataDir.listFiles();
                      IndexWriter indexWriter = new IndexWriter(indexDir,luceneAnalyzer,true);
                      long startTime = new Date().getTime();
                      for(int i = 0; i < dataFiles.length; i++){
                      if(dataFiles[i].isFile() && dataFiles[i].getName().endsWith(".txt")){
                      System.out.println("Indexing file " + dataFiles[i].getCanonicalPath());
                              		Document document = new Document();
                      Reader txtReader = new FileReader(dataFiles[i]);
                      document.add(Field.Text("path",dataFiles[i].getCanonicalPath()));
                      document.add(Field.Text("contents",txtReader));
                      indexWriter.addDocument(document);
                      }
                      }
                      indexWriter.optimize();
                      indexWriter.close();
                      long endTime = new Date().getTime();
                      System.out.println("It takes " + (endTime - startTime)
                      + " milliseconds to create index for the files in directory "
                      + dataDir.getPath());
                      }
                      }
                      

          在清單1中,我們注意到類(lèi) IndexWriter 的構(gòu)造函數(shù)需要三個(gè)參數(shù),第一個(gè)參數(shù)指定了所創(chuàng)建的索引要存放的位置,他可以是一個(gè) File 對(duì)象,
          也可以是一個(gè) FSDirectory 對(duì)象或者 RAMDirectory 對(duì)象。
          第二個(gè)參數(shù)指定了 Analyzer 類(lèi)的一個(gè)實(shí)現(xiàn),也就是指定這個(gè)索引是用哪個(gè)分詞器對(duì)文擋內(nèi)容進(jìn)行分詞。
          第三個(gè)參數(shù)是一個(gè)布爾型的變量,如果為 true 的話就代表創(chuàng)建一個(gè)新的索引,為 false 的話就代表在原來(lái)索引的基礎(chǔ)上進(jìn)行操作。
          接著程序遍歷了目錄下面的所有文本文檔,并為每一個(gè)文本文檔創(chuàng)建了一個(gè) Document 對(duì)象。
          然后把文本文檔的兩個(gè)屬性:路徑和內(nèi)容加入到了兩個(gè) Field 對(duì)象中,接著在把這兩個(gè) Field 對(duì)象加入到 Document 對(duì)象中,
          最后把這個(gè)文檔用 IndexWriter 類(lèi)的 add 方法加入到索引中去。這樣我們便完成了索引的創(chuàng)建。接下來(lái)我們進(jìn)入在建立好的索引上進(jìn)行搜索的部分。

          搜索文檔

          利用Lucene進(jìn)行搜索就像建立索引一樣也是非常方便的。在上面一部分中,我們已經(jīng)為一個(gè)目錄下的文本文檔建立好了索引,現(xiàn)在我們就要在這個(gè)索引上進(jìn)行搜索以找到包含某個(gè)關(guān)鍵詞或短語(yǔ)的文檔。Lucene提供了幾個(gè)基礎(chǔ)的類(lèi)來(lái)完成這個(gè)過(guò)程,它們分別是呢IndexSearcher, Term, Query, TermQuery, Hits. 下面我們分別介紹這幾個(gè)類(lèi)的功能。

          Query

          這是一個(gè)抽象類(lèi),他有多個(gè)實(shí)現(xiàn),比如TermQuery, BooleanQuery, PrefixQuery. 這個(gè)類(lèi)的目的是把用戶輸入的查詢字符串封裝成Lucene能夠識(shí)別的Query。

          Term

          Term是搜索的基本單位,一個(gè)Term對(duì)象有兩個(gè)String類(lèi)型的域組成。生成一個(gè)Term對(duì)象可以有如下一條語(yǔ)句來(lái)完成:Term term = new Term(“fieldName”,”queryWord”); 其中第一個(gè)參數(shù)代表了要在文檔的哪一個(gè)Field上進(jìn)行查找,第二個(gè)參數(shù)代表了要查詢的關(guān)鍵詞。

          TermQuery

          TermQuery是抽象類(lèi)Query的一個(gè)子類(lèi),它同時(shí)也是Lucene支持的最為基本的一個(gè)查詢類(lèi)。生成一個(gè)TermQuery對(duì)象由如下語(yǔ)句完成: TermQuery termQuery = new TermQuery(new Term(“fieldName”,”queryWord”)); 它的構(gòu)造函數(shù)只接受一個(gè)參數(shù),那就是一個(gè)Term對(duì)象。

          IndexSearcher

          IndexSearcher是用來(lái)在建立好的索引上進(jìn)行搜索的。它只能以只讀的方式打開(kāi)一個(gè)索引,所以可以有多個(gè)IndexSearcher的實(shí)例在一個(gè)索引上進(jìn)行操作。

          Hits

          Hits是用來(lái)保存搜索的結(jié)果的。

          介紹完這些搜索所必須的類(lèi)之后,我們就開(kāi)始在之前所建立的索引上進(jìn)行搜索了,清單2給出了完成搜索功能所需要的代碼。


          清單2 :在建立好的索引上進(jìn)行搜索
          package TestLucene;
                                  import java.io.File;
                                  import org.apache.lucene.document.Document;
                                  import org.apache.lucene.index.Term;
                                  import org.apache.lucene.search.Hits;
                                  import org.apache.lucene.search.IndexSearcher;
                                  import org.apache.lucene.search.TermQuery;
                                  import org.apache.lucene.store.FSDirectory;
                                  /**
                                  * This class is used to demonstrate the
                                  * process of searching on an existing
                                  * Lucene index
                                  *
                                  */
                                  public class TxtFileSearcher {
                                  public static void main(String[] args) throws Exception{
                                  String queryStr = "lucene";
                                  //This is the directory that hosts the Lucene index
                                  File indexDir = new File("D:\\luceneIndex");
                                  FSDirectory directory = FSDirectory.getDirectory(indexDir,false);
                                  IndexSearcher searcher = new IndexSearcher(directory);
                                  if(!indexDir.exists()){
                                  System.out.println("The Lucene index is not exist");
                                  return;
                                  }
                                  Term term = new Term("contents",queryStr.toLowerCase());
                                  TermQuery luceneQuery = new TermQuery(term);
                                  Hits hits = searcher.search(luceneQuery);
                                  for(int i = 0; i < hits.length(); i++){
                                  Document document = hits.doc(i);
                                  System.out.println("File: " + document.get("path"));
                                  }
                                  }
                                  }
                                  

          在清單2中,類(lèi)IndexSearcher的構(gòu)造函數(shù)接受一個(gè)類(lèi)型為Directory的對(duì)象,Directory是一個(gè)抽象類(lèi),它目前有兩個(gè)子類(lèi):FSDirctory和RAMDirectory. 我們的程序中傳入了一個(gè)FSDirctory對(duì)象作為其參數(shù),代表了一個(gè)存儲(chǔ)在磁盤(pán)上的索引的位置。構(gòu)造函數(shù)執(zhí)行完成后,代表了這個(gè)IndexSearcher以只讀的方式打開(kāi)了一個(gè)索引。然后我們程序構(gòu)造了一個(gè)Term對(duì)象,通過(guò)這個(gè)Term對(duì)象,我們指定了要在文檔的內(nèi)容中搜索包含關(guān)鍵詞”lucene”的文檔。接著利用這個(gè)Term對(duì)象構(gòu)造出TermQuery對(duì)象并把這個(gè)TermQuery對(duì)象傳入到IndexSearcher的search方法中進(jìn)行查詢,返回的結(jié)果保存在Hits對(duì)象中。最后我們用了一個(gè)循環(huán)語(yǔ)句把搜索到的文檔的路徑都打印了出來(lái)。好了,我們的搜索應(yīng)用程序已經(jīng)開(kāi)發(fā)完畢,怎么樣,利用Lucene開(kāi)發(fā)搜索應(yīng)用程序是不是很簡(jiǎn)單。


          轉(zhuǎn)載地址:http://www-128.ibm.com/developerworks/cn/java/j-lo-lucene1/
          posted on 2008-11-01 17:57 馬光軍 閱讀(310) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 轉(zhuǎn)載Lucene

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 德钦县| 普定县| 沛县| 南靖县| 牡丹江市| 得荣县| 滨州市| 石棉县| 治县。| 札达县| 中方县| 常宁市| 平顶山市| 渝中区| 湖南省| 库伦旗| 库尔勒市| 胶州市| 辉南县| 平南县| 桃园市| 原阳县| 福贡县| 达拉特旗| 沅江市| 若羌县| 乌兰察布市| 拜泉县| 平邑县| 伊通| 五大连池市| 龙泉市| 安仁县| 南部县| 临洮县| 泸定县| 安顺市| 永嘉县| 台安县| 克拉玛依市| 泌阳县|