?

在第一章中作者 主要講了Lucene 是什么 能用來干什么, 以及一個 indexing 和 searching 的例子, 通過例子講解了一點基本(核心)概念.給讀者一個基本的Lucene 概況. 然后又介紹了現(xiàn)在流行的 搜索框架.

我們主要來看看 這個 indexing and searching 例子 然后了解一些基本概念.

package?lia.meetlucene;

import?org.apache.lucene.index.IndexWriter;
import?org.apache.lucene.analysis.standard.StandardAnalyzer;
import?org.apache.lucene.document.Document;
import?org.apache.lucene.document.Field;

import?java.io.File;
import?java.io.IOException;
import?java.io.FileReader;
import?java.util.Date;

/**
?*?This?code?was?originally?written?for
?*?Erik's?Lucene?intro?java.net?article
?*/
public?class?Indexer?{

??public?static?void?main(String[]?args)?throws?Exception?{
????if?(args.length?!=?2)?{
??????throw?new?Exception("Usage:?java?"?+?Indexer.class.getName()
????????+?"?<index?dir>?<data?dir>");
????}
????File?indexDir?=?new?File(args[0]); // 在該目錄中創(chuàng)建Lucene Incex
????File?dataDir?=?new?File(args[1]); // 該目錄中存放備索引的文件

????long?start?=?new?Date().getTime();
????int?numIndexed?=?index(indexDir,?dataDir);
????long?end?=?new?Date().getTime();

????System.out.println("Indexing?"?+?numIndexed?+?"?files?took?"
??????+?(end?-?start)?+?"?milliseconds");
??}

??public?static?int?index(File?indexDir,?File?dataDir)
????throws?IOException?{

????if?(!dataDir.exists()?||?!dataDir.isDirectory())?{
??????throw?new?IOException(dataDir
????????+?"?does?not?exist?or?is?not?a?directory");
????}

????IndexWriter?writer?=?new?IndexWriter(indexDir,
??????new?StandardAnalyzer(),?true);?????????????? //(1)創(chuàng)建 Lucene Index
????writer.setUseCompoundFile(false);

????indexDirectory(writer,?dataDir);

????int?numIndexed?=?writer.docCount();
????writer.optimize();
????writer.close();?????????????????????????????? // close index
????return?numIndexed;
??}

??private?static?void?indexDirectory(IndexWriter?writer,?File?dir)
????throws?IOException?{

????File[]?files?=?dir.listFiles();

????for?(int?i?=?0;?i?<?files.length;?i++)?{
??????File?f?=?files[i];
??????if?(f.isDirectory())?{
????????indexDirectory(writer,?f);??//(2)?recurse
??????}?else?if?(f.getName().endsWith(".txt"))?{
????????indexFile(writer,?f);
??????}
????}
??}

??private?static?void?indexFile(IndexWriter?writer,?File?f)
????throws?IOException?{

????if?(f.isHidden()?||?!f.exists()?||?!f.canRead())?{
??????return;
????}

????System.out.println("Indexing?"?+?f.getCanonicalPath());

????Document?doc?=?new?Document();
????doc.add(Field.Text("contents",?new?FileReader(f)));? // (3) index file content
????doc.add(Field.Keyword("filename",?f.getCanonicalPath())); // (4) index file name
????writer.addDocument(doc);?????????????????? //(5) add document in Lucene index
??}
}

上面的Indexer 使用了幾行 Lucene的API, 來indexing 一個目錄下面的文件. 運行時候 需要兩個參數(shù) , 一個保存index的目錄和要索引的文件目錄.

在上面的類中,需要下面的一些Lucene classes 來執(zhí)行 indexing 處理:

IndexWriter

Directory

Analyzer

Document

Field

IndexWriter 是indexing 處理時用到的中心組件,該類create 新index 并且添加documents 到已經(jīng)存在的index, BTW,在Lucene中還有別的方法來更新index.

Directory: 用來存放index文件的文件目錄,該類是個抽象類,用幾個子類可以使用,上面使用了File來代表文件路徑,在Lucene中用兩個主要的Directory子類,一個FSDirectory,一個 RAMDirectory,前者是把index保存到硬盤中的;后者是保存在內存中的,在內存中處理數(shù)度當然就相應的快一些 了但只適合于小文件.

Analyzer: 在文件備索引以前要先通過Analyzer分析,去掉一些對search無用的詞語(如英語中 的小詞 in at a 等等,在Lucene中被稱為stop words 的詞),還可以處理大小寫的問題(是大小寫相關啊 還是不相關),使用Lucene時候 選擇Analyzer是關鍵.

Document: 代表一些Fields的集合.可以想象為一些數(shù)據(jù)的集合.

Field: 在index中的每一個Document中都包含一些 命名的Fields 用Field來構造, 每一個field都是的搜索是符合要求和不符合要求的index中的一些數(shù)據(jù),Lucene提供了四種不同的Field,

1,Keyword? 不分析 只索引和保存,象一些特殊信息 不可以分割的 如 電話號碼 網(wǎng)站 Email 等.

2,UnIndexed 既不索引也不分析,只是把值保存在index中.該類型適合用來顯示搜索結果的field,但是你從來不搜索該顯示的數(shù)據(jù),如URL

3,UnStored UnIndexed的對立面, 分析和索引但是不保存在index中,適合大型數(shù)據(jù) 只搜索但是不顯示原始數(shù)據(jù).

4,Test 分析且索引,如果索引數(shù)據(jù)是String則也保存在index中, 如果是Reader則不保存.