Lucene 核心攻略

Lucene 核心攻略

lucene的檢索算法屬於索引檢索,即用空間來換取時間,對需要檢索的文件、字符流進行全文索引,在檢索的時候對索引進行快速的檢索,得到檢索位置,這個位置記錄檢索詞出現的文件路徑或者某個關鍵詞。

analysis:分析器,切詞

document:索引存儲時的文檔結構管理器,類似表結構

index:索引管理,包括建立,刪除索引

queryParser:查詢分析器,實現查詢關鍵詞的運算

search:檢索管理,根據查詢條件,檢索得到結果

store:數據存儲管理,IO操作

Directory:索引存放的位置;lucene 提供了兩種索引存放的位置,一種是磁盤,一種是內存。

Hits:在搜索完成之後,需要把搜索結果返回並顯示給用戶,只有這樣才算是完成搜索的目的。

IndexWriter:用於更新或創建索引。

Lucene的索引結構是文檔(Document)形式的。

1.將文檔傳給分詞組件(Tokenizer),分詞組件根據標點符號和停詞將文檔分成詞元(Token),並將標點符號和停詞去掉。

2.再將詞元傳給語言處理組件(Linguistic Processor) ,詞元會變成最基本的詞根形式。

3.得到的詞元傳給索引組件(Indexer),索引組件處理得到索引結構,得到關鍵字、出現頻率、出現位置分別作為詞典文件

(Term Dictionary)、頻率文件(frequencies)和位置文件(positions)保存起來,然後通過二元搜索算法快速查找關鍵字。

示例:

一篇文檔有多種信息,如題目,作者,修改時間,內容等。

不同類型的信息用不同的Field 來表示,在本例子中,一共有兩類信息進行了索引,一個是文件路徑,一個是文件內容。

其中FileReader 的SRC_FILE 就表示要索引的源文件。

索引建立步驟:

1、創建Directory

2、創建Writer

3、創建文檔並且添加索引

4、查詢索引的基本信息

5、刪除和更新索引

public class HelloLucene {

public static void main(String[] args) throws IOException, ParseException {

// 0. Specify the analyzer for tokenizing text.

// The same analyzer should be used for indexing and searching

StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_40);

// 1. create the index

Directory index = new RAMDirectory();

IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_40, analyzer);

IndexWriter w = new IndexWriter(index, config);

addDoc(w, "Lucene in Action", "193398817");

addDoc(w, "Lucene for Dummies", "55320055Z");

addDoc(w, "Managing Gigabytes", "55063554A");

addDoc(w, "The Art of Computer Science", "9900333X");

w.close();

// 2. query

String querystr = args.length > 0 ? args[0] : "lucene";

// the "title" arg specifies the default field to use

// when no field is explicitly specified in the query.

Query q = new QueryParser(Version.LUCENE_40, "title", analyzer).parse(querystr);

// 3. search

int hitsPerPage = 10;

IndexReader reader = DirectoryReader.open(index);

IndexSearcher searcher = new IndexSearcher(reader);

TopScoreDocCollector collector = TopScoreDocCollector.create(hitsPerPage, true);

searcher.search(q, collector);

ScoreDoc[] hits = collector.topDocs().scoreDocs;

// 4. display results

System.out.println("Found " + hits.length + " hits.");

for(int i=0;i

int docId = hits[i].doc;

Document d = searcher.doc(docId);

System.out.println((i + 1) + ". " + d.get("isbn") + "\t" + d.get("title"));

}

// reader can only be closed when there

// is no need to access the documents any more.

reader.close();

}

private static void addDoc(IndexWriter w, String title, String isbn) throws IOException {

Document doc = new Document();

doc.add(new TextField("title", title, Field.Store.YES));

// use a string field for isbn because we don't want it tokenized

doc.add(new StringField("isbn", isbn, Field.Store.YES));

w.addDocument(doc);

}

}

搜索過程:示例如上

IndexReader 將磁盤上的索引信息讀入到內存,INDEX_DIR 就是索引文件存放的位置。

創建IndexSearcher 準備進行搜索。

創建Analyer 用來對查詢語句進行詞法分析和語言處理。

創建QueryParser 用來對查詢語句進行語法分析。

QueryParser 調用parser 進行語法分析,形成查詢語法樹,放到Query 中。

IndexSearcher 調用search 對查詢語法樹Query 進行搜索,得到結果TopScoreDocCollector 。

在Lucene中,詞典和倒排是分開存儲的,詞典存儲在.tii和.tis文件中,而倒排又分為兩部分存儲,第一部分是文檔號和詞頻信息,存儲在.frq中;另一部分是詞的位置信息,存儲在.prx文件中。

所謂正向信息:

lucene 在存儲它的全文索引結構時,是有層次結構的,

涉及到5個層次:索引(Index) –> 段(segment) –> 文檔(Document) –> 域(Field) –> 詞(Term)

索引(Index):一個目錄一個索引,在Lucene中一個索引是放在一個文件夾中的。

段(Segment):一個索引可以包含多個段,段與段之間是獨立的,添加新文檔可以生成新的段,不同的段可以合併。

文檔(Document):文檔是我們建索引的基本單位,不同的文檔是保存在不同的段中的,一個段可以包含多篇文檔。

域(Field):一篇文檔包含不同類型的信息,可以分開索引.

詞(Term):詞是索引的最小單位,是經過詞法分析和語言處理後的字符串。

所謂反向信息:

保存了詞典到倒排表的映射:詞(Term) –> 文檔(Document)

更多內容請關注每日編程。


分享到:


相關文章: