【轉載】Lucene學習筆記(一)

本人學習Lucene真實筆記,其中如有表達、理解錯誤或不清的地方希望大家指正,同時希望對需要的朋友有所幫助。




申明:此文章中說到的分詞器就是分析器(後邊小節會講到)中的一種,不要理解錯了。



一、Lucene基礎:
大綱:1. 信息獲取與搜索引擎的發展
2. Lucene的歷史
3. 建立索引(索引庫)與搜索

1. 信息獲取技術包含:信息的表示、存儲、組織和對信息的訪問方法。信息的表示和組織是爲了用戶更容易的訪問到需要的信息。

1.1 一般來說,信息獲取的流程分爲以下四步:

1.1.1 獲取信息之前,要構建文本數據庫,即將來需要進行檢索的數據(被檢索的數據)
1.1.2 需要建立文檔的索引,通過文檔索引可以檢索到對應的文本數據庫中對應的數據;
有很多建立文檔索引的方法,但是用的最多的還是"倒排索引技術",其中Lucene就是採用的這種建立文檔索引的技術
1.1.3 完成文檔索引的建立之後就可以進行檢索了,此時需要用戶提供一個查詢關鍵字,該關鍵字將被分析
然後利用一些文本處理技術進行處理,當然也可以根據具體的需求進行一系列的處理。
1.1.4 查詢關鍵字準備好之後,進入查詢,根據查詢關鍵字可以與文檔索引中的數據得到匹配
進而得到文本數據庫中與匹配上的文檔索引對應的數據,然後反饋給用戶,當然反饋之前我們可以進行排序等處理,
讓最接近用戶需求的信息排在最前面顯示

2. 搜索引擎:分爲"全文搜索引擎(FullText Search Engine)"和"分類目錄(Directory)"

2.1 全文搜索引擎:通過一個叫網絡機器人(Spider)或者叫網絡蜘蛛(Crawlers)的軟件,自動分析網絡上的各種連接並且獲取網頁信息內容
而且會按照規則加以分析整理,記入數據庫。

優缺點:使用關鍵字和一定的語法;全文搜索引擎因爲依靠網絡機器人等收集數據,所以數據庫的容量非常龐大,但是它的查詢往往不準確。

實例:像Google和百度都是全文搜索引擎

2.2 分類目錄:通過人工的方式收集整理網站資料形成數據庫。

優缺點:建立多級目錄樹對網站進行分類;分類目錄因爲依靠人工收集和整理網站,所以數據庫數據容量非常有限,但是它能提供非常準確的查詢。

實例:像搜狐、新浪、網易等都是分類目錄

2.3 搜索引擎的概念:

2.3.1 第一代搜索引擎:是依靠人工提煉的分類目錄搜索,以"搜狐"爲代表
2.3.2 第二代搜索引擎:是依靠與機器抓取,並建立在超級鏈接的分析技術基礎之上的網頁搜索
特點是信息量大,更新及時,但是搜索結果準確度不高。以"Google"爲代表
2.3.3 第三代搜索引擎:是把"智能化"、"人機交互"等功能融入了主流。將自動分類技術、中文內容分析技術和區域識別技術應用到大型搜索引擎中,
除了在信息檢索速度、更新頻率等基礎技術指標方面處於領先地位外,它的網頁相關檢索、拼音糾錯、模糊查詢和語義查詢技術也具有很高的水平。
此外,還兼備了新聞、MP3、Flash、圖片等搜索功能,已能夠提供全面、綜合的信息搜索服務!

3. Lucene的歷史:Lucene是一個支持全文檢索的開源工具包。

3.1 什麼是全文檢索與全文檢索系統

3.1.1 全文檢索:指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,
指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程序就會根據事先建立的索引進行查找,並將查找的結果反饋給用戶。
這個過程類似與通過字典中的檢索字表查詢漢字的過程!

** 全文檢索的方法主要分爲:按字檢索和按詞檢索兩種方法!

3.1.1.1 按字檢索:指對於文章中的每個字都建立索引,檢索時將詞分爲字的組合。
對於各種不同的語言而言,字有不同的含義,比如英文中字與詞實際上是合一的,而中文中的字與詞就有很大區別。

3.1.1.2 按詞檢索:指對文章中的詞,即語義單位建立索引,檢索時按詞檢索,並且可以處理同義項等。
英文等西方文字由於按照空白切分詞,因此實際上與按字檢索比較類似,添加同義處理也很容易。
中文文字則需要切分字詞,以達到按詞檢索的目的,關於這方面的問題,
是當前全文檢索技術尤其是中文全文檢索技術中的難點,這裏不做詳述,
Lucene對這方面有自己的解決方法。

3.1.2 全文檢索系統:是按照全文檢索理論建立起來的用於提供全文檢索服務的軟件系統。
一般來說全文檢索需要具備建立索引和提供查詢的基本功能,
此外現代的全文檢索系統還需要具有方便的用戶接口、面向WWW的開發接口、二次應用開發接口等。

** 功能上:全文檢索系統具有建立索引、處理查詢並返回查詢結果集、增加索引、優化索引結構等功能,外圍則有各種應用程序所具有的功能組成。
** 結構上:全文檢索系統具有索引引擎、查詢引擎、文本分析引擎、對外接口等,加上各種應用程序共同構成了全文檢索系統。

3.2 什麼是Lucene :Lucene是Apache軟件基金會Jakarta項目組的一個子項目(目前已經提升爲了一個頂級項目),是一個開放源代碼的全文檢索引擎工具包,
即它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,它提供了完整的查詢引擎和索引引擎及部分文本分析引擎(英文和德文兩種西方語言)。
Lucene的目的是爲軟件開發人員提供一個簡單易用的工具包(可說成提供簡易的API接口),以方便在目標系統中實現全文檢索的功能,
或者是以此爲基礎建立起完整的全文檢索引擎。Lucene作者是Doug Cutting,是一位資深全文索引/檢索專家,Lucene是Doug Cuuting的Middle Name(中間名)。

例如:Eclipse的幫助部分就是使用了Lucene作爲檢索引擎!

3.3 Lucene能做什麼(功能):Lucene可以對任何的數據做索引和搜索!!Lucene不管數據源是什麼格式,只要它能被轉化爲文字(文本)的形式,
就可以被Lucene分析利用。也就是說Lucene針對的檢索數據是文本格式的數據!!
也就是說不管數據源是Word、PDF、Html還是其他什麼形式的文件,只要你可以從中抽取出文字形式的內容就可以被Lucene所用,
就可以用Lucene對他們進行索引進而進行搜索!!

4.建立索引與搜索:建立索引和搜索是搜索引擎最重要也是最基礎的兩個部分,不過這涉及到方方面面很多內容,下邊我們先來簡單瞭解,以後章節將會深入體會具體內涵。

4.1 索引:傳統的基本的查詢方法可以通過順序掃描文本的方式來實現,這被成爲"順序查詢",
不需要對文檔集合中的數據信息做任何的預處理,當用戶查詢時直接在文檔中進行簡單的字符串匹配就可以實現,
但是這種方法如果遇到非常龐大的文檔集合,而還是這樣順序查詢,那麼它的效率會非常低,達不到用戶的需求。
因此,人們就創建了非常多的查詢方式:使用索引就是一種比較常用的方式!

4.1.1 概念:索引是在搜索時使用到的一種特殊的數據結構。當文檔的數據量比較龐大,並且文檔中的信息相對穩定(不會隨時變化)時,
建立索引可以大大提高查詢的效率。

**注意:索引結構不支持快速的信息更新,就是說建立完索引後,如果文檔中的信息發生了變化,
那麼必須重新建立索引(即同時也要對索引更新),這樣才能使索引檢索到最新的文檔中的信息!

**注意:在實際中,通常是定期更新索引,並把索引添加(覆蓋)到原索引中實現的。

4.1.2 應用:使用的索引進行查詢的時候,首先對需要索引的文檔進行預處理,建立關於這些文檔的索引機構(索引庫,就是建立索引)。

4.1.3 索引的技術種類:倒排索引、後綴數組和簽名文件。

4.1.3.1 倒排索引:目前倒排索引技術是應用最爲廣泛的索引技術,它對於關鍵詞的搜索非常有效,Lucene就是使用的倒排索引技術。

4.1.3.2 後綴數組:在短語查詢中具有很快的速度,但是這樣的數據結構在構造和維護時都比較複雜一些。

4.1.3.3 簽名文件:在20世紀80年代時期比較流行,但目前已被倒排索引技術超越!

4.2.4 舉例:爲一個文檔文件建立索引數據,索引數據保存到"C://indexWriter"

//將索引保存到指定的C://indexWriter目錄,new SimpleAnalyzer()爲分詞器,true是看指定目錄中是否有要創建的索引,如果有刪除,用新的覆蓋
IndexWriter writer = new IndexWriter("C://indexWriter",new SimpleAnalyzer(),true);
//指定文本文檔數據的內容
File file = new File("C://sourceFile.txt");
//將文本文檔放入索引中,以便使用分詞器對其進行分詞,不過文檔放入索引前要被包裝成一個Document對象
(具體的封裝方法,要將文件分解成如文件名、內容等,把這些文件名、
內容分別用Field對象包裝(Field是鍵值的形式,即Field有鍵和值兩個屬性所以可以這樣保存new Field("fileName","文件名")對象),
然後在添加到Document對象中,這樣才實現將文檔數據包裝成Document對象),這裏只做一個示意
writer.addDocument(Document(file));
//優化索引
writer.optimize();
//關閉寫入流對象,同時關閉的時候,寫入流纔會將索引寫入到磁盤的C://indexWriter目錄中
writer.close();

**注意:我們沒有看到writer.writer();進行寫入的類似方法,這是因爲在掉用writer.close()方法的時候會將索引寫入磁盤,
所以不需要調用類似writer()的方法。


4.2 搜索:檢索系統在建立好索引之後,就可以對用戶的查詢做出響應,只不過該響應過程是通過搜索過程完成來實現的。
搜索的目的就是爲用戶提供高質量的搜索結果。既要求搜索結果快,有要求結果準確,這就涉及到搜索算法的問題。
此外,搜索程序在搜索到一定數量的結果之後,就會以一定的方式反饋給用戶,其中我們會顧及以什麼樣的格式、
什麼樣的次序(當然會希望想要的結果排在最前面)來顯示搜索結果,這會涉及到搜索結果排序的問題。
Lucene之所以會這麼優秀,是因爲它擁有高效的搜索算法和豐富的排序方法。

例子:
//把索引建立到內存中,而不是磁盤
Directory dir = new RAMDirectory();
//創建分詞器對象,對於要建立索引的文檔數據和用戶輸入的搜索數據進行分詞。注意:建立索引和搜索要用相同的分詞器
Analyzer analyzer = new SimpleAnalyzer();
//建立索引書寫流對象
IndexWriter writer = new IndexWriter(dir, analyzer, true);
//創建要建立索引的數據(這裏爲了簡便沒有從文件中讀取)
String[] datas = {"abcde","abcdeabcde","abcdefghij","ace","eca","aceace","aceabc"};
//將要建立索引的數據添加到索引書寫器中進行處理(當然還是要先將數據包裝成Document對象)
for(int i = 0; i < datas.length; i++){
//每一個元素都保存成Document對象,也就是datas循環完後相當於有7個被索引的文件,因爲一個Document對應一個文件
Document document = new Document();
//對每個datas中的元素都保存成一個Field對象,再把Field對象保存到Document,然後將Document添加到索引寫入器進行處理
document.addField(Field.Text("content",datas[i]));
writer.addDocument(document);
}
//進行處理,並將索引保存到內存中
writer.close();
/*---------------------下邊進行搜索-----------------------*/

//創建搜索器對象,並且與被搜索的索引目錄相綁定,也就是說當搜索器執行搜索的時候會到dir指定的地方進行搜索
IndexSearch search = new IndexSearch(dir);
//模擬用戶輸入的搜索關鍵字
String key = "ace";
//初始化接收搜索結果的結果集對象:初始爲空
Hits hits = null;
/*
創建搜索解析器:就是將用戶輸入的查詢關鍵字先通過分詞器進行分詞,
然後再封裝成Lucene要求的查詢條件的格式,即解析封裝成Query對象
這裏使用的"content"就是Filed對象中的第一個參數值,就是創建針對content鍵(字段)創建的查詢條件
*/
QueryParser queryParser = new QueryParser("content", analyzer);
//生成查詢條件
Query query = queryParser.parse(key);
System.out.println(query.toString());//打印查詢條件的內容,即真實Lucene將會怎麼樣查詢
//進行查詢,並且返回結果集,結果集中封裝的是一個以Document對象爲元素的集合
hits = search.search(query);
//輸出結果
for(int i = 0; i < hits.length(); i++){
Document document = hits.doc(i);
System.out.println("對應的內容爲:" + document.get("content"));
}
//關閉搜索器
search.close();

4.3 倒排索引:是一種面向單詞的索引機制,利用倒排索引可以提高檢索時的速度。
通常情況下,倒排索引結構由"詞典"和"出現情況"兩部分組成。
對於每一個單詞,都會有一個詞彙列表記錄單詞在所有文檔中出現的位置
這裏的位置指的是單詞在文檔中的位置(文本中的第幾個單詞),也可以是單詞對應的字符的位置(文本中的第幾個字符)
**注意:這裏倒排索引是針對每一個單詞,記錄它在所有文檔中出現的位置;而不是對每一個文檔中這個單詞的位置都分別記錄(這是一般索引的做法)

**倒排索引與一般索引方式對比:

4.3.1 一般索引:建立的是"文檔到單詞"的映射關係索引,即在生成的索引文件中記錄的是"文檔到單詞"的映射關係。
例如:有文章A和B,那麼一般索引的方法,對於文章A建立一個索引記錄(可認爲是索引文件),記錄文章A中的所有單詞的位置和出現次數情況等,
對於文章B又會建立一個索引記錄,然後記錄文章B中所有單詞的位置和出現次數情況。

4.3.2 倒排索引:建立的是"單詞到文檔"的映射關係索引,即在生成的索引文件中記錄的是"單詞到文檔"的映射關係。
例如:有文章A和B,且A和B中都有dog和pig單詞而B中有cat單詞,那麼倒排索引的方法,
它是對於每一個不同的單詞與文章建立關聯,就是倒排索引是針對每個單詞建立一個索引記錄,
具體的就是dog單詞對應一個索引記錄(可認爲是一個索引文件),
dog對應的索引記錄中記錄了dog出現情況在A、B中個出現一次,還會記錄出現的位置
這樣倒排索引的結果就是對dog、pig和cat分別建立一個索引記錄,又因爲用戶查詢的時候都是輸入關鍵字進行查詢,
這樣就可以很快的找到所有出現對應查詢關鍵的單詞的出現情況和位置,比起一般索引會非常的節省時間,因爲如果是一般索引的話,
會對每一個文章中的每一個索引進行遍歷,看看是否有搜索的單詞,有的話拿出它的出現次數和位置等信息,這樣會很耗時!
發佈了101 篇原創文章 · 獲贊 26 · 訪問量 29萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章