Lucene 研究
一、Lucene簡介
Lucene是有知名全文檢索/索引專家Doug Cutting采用Java語言開發的基于全文搜索的軟件工具,之后貢獻給Apache軟件基金會做為一個開源項目,成為一個開放源代碼的全文檢索引擎工具包,由于他的高性能,可伸縮性而且經歷了很長時間的沉淀,已經是很成熟的項目,被廣泛集成于系統軟件中,甚至一些商用軟件也采用了Lucene做為其內部全文檢索子系統的核心,如IBM的開源軟件Eclipse 的幫助文檔,也是采用了Lucene做 為其全文搜索引擎。Lucene 能夠為文本類型的數據建立索引,所以你只要能把你要索引的數據格式轉化的文本的,Lucene 就能對你的文檔進行索引和搜索。比如你要對一些 HTML 文檔,PDF 文檔進行索引的話你就首先需要把 HTML 文檔和 PDF 文檔轉化成文本格式的,然后將轉化后的內容交給 Lucene 進行索引,然后把創建好的索引文件保存到磁盤或者內存中,最后根據用戶輸入的查詢條件在索引文件上進行查詢。不指定要索引的文檔的格式也使 Lucene 能夠幾乎適用于所有的搜索應用程序。
下載地址:http://www.apache.org/dyn/closer.cgi/lucene/java/4.9.0
二、Lucene的優點
1、索引文件格式獨立于應用平臺。Lucene定義了一套以8位字節為基礎的索引文件格式,使得兼容系統或者不同平臺的應用能夠共享建立的索引文件。
2、在傳統全文檢索引擎的倒排索引的基礎上,實現了分塊索引,能夠針對新的文件建立小文件索引,提升索引速度。然后通過與原有索引的合并,達到優化的目的。
3、優秀的面向對象的系統架構,使得對于Lucene擴展的學習難度降低,方便擴充新功能。
4、設計了獨立于語言和文件格式的文本分析接口,索引器通過接受Token流完成索引文件的創立,用戶擴展新的語言和文件格式,只需要實現文本分析的接口。
5、已經默認實現了一套強大的查詢引擎,用戶無需自己編寫代碼即使系統可獲得強大的查詢能力,Lucene的查詢實現中默認實現了布爾操作、模糊查詢、分組查詢等等。
三、什么是全文檢索
全文檢索是指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時,檢索程序就根據事先建立的索引進行查找,并將查找的結果反饋給用戶的檢索方式。這個過程類似于通過字典中的檢索字表查字的過程。
全 文檢索的方法主要分為按字檢索和按詞檢索兩種。按字檢索是指對于文章中的每一個字都建立索引,檢索時將詞分解為字的組合。對于各種不同的語言而言,字有不 同的含義,比如英文中字與詞實際上是合一的,而中文中字與詞有很大分別。按詞檢索指對文章中的詞,即語義單位建立索引,檢索時按詞檢索,并且可以處理同義 項等。英文等西方文字由于按照空白切分詞,因此實現上與按字處理類似,添加同義處理也很容易。中文等東方文字則需要切分字詞,以達到按詞索引的目的,關于 這方面的問題,是當前全文檢索技術尤其是中文全文檢索技術中的難點,在此不做詳述。
四、Lucene系統結構
系統結構與源碼組織圖:
從圖中我們清楚的看到,Lucene的系統由基礎結構封裝、索引核心、對外接口三大部分組成。其中直接操作索引文件的索引核心又是系統的重點。Lucene的將所有源碼分為了7個模塊(在java語言中以包即package來表示):Analysis,Document,Index,QueryParser,Search,Store,Util.各個模塊所屬的系統部分也如上圖所示。需要說明的是org.apache.lucene.queryPaser是做為org.apache.lucene.search的語法解析器存在,不被系統之外實際調用,因此這里沒有當作對外接口看待,而是將之獨立出來。
從面象對象的觀點來考察,Lucene應用了最基本的一條程序設計準則:引入額外的抽象層以降低耦合性。首先,引入對索引文件的操作org.apache.lucene.store的封裝,然后將索引部分的實現建立在(org.apache.lucene.index)其之上,完成對索引核心的抽象。在索引核心的基礎上開始設計對外的接口org.apache.lucene.search與org.apache.lucene.analysis。在每一個局部細節上,比如某些常用的數據結構與算法上,Lucene也充分的應用了這一條準則。在高度的面向對象理論的支撐下,使得Lucene的實現容易理解,易于擴展。
Lucene在系統結構上的另一個特點表現為其引入了傳統的客戶端服務器結構以外的的應用結構。Lucene可以作為一個運行庫被包含進入應用本身中去,而不是做為一個單獨的索引服務器存在。這自然和Lucene開放源代碼的特征分不開,但是也體現了Lucene在編寫上的本來意圖:提供一個全文索引引擎的架構,而不是實現。
包名 |
功能 |
org.apache.lucene.analysis |
語言分析器,主要用于的切詞,支持中文主要是擴展此類 |
org.apache.lucene.document |
索引存儲時的文檔結構管理,類似于關系型數據庫的表結構 |
org.apache.lucene.index |
索引管理,包括索引建立、刪除等 |
org.apache.lucene.queryParser |
查詢分析器,實現查詢關鍵詞間的運算,如與、或、非等 |
org.apache.lucene.search |
檢索管理,根據查詢條件,檢索得到結果 |
org.apache.lucene.store |
數據存儲管理,主要包括一些底層的I/O操作 |
org.apache.lucene.util |
一些公用類 |
Lucene主要邏輯圖:
Lucene功能強大,但從根本上說,主要包括兩塊:一是文本內容經切詞后索引入庫;二是根據查詢條件返回結果。
搜索應用程序和 Lucene 之間的關系
如圖:用戶要找Document得信息。最先將為Document文檔建立Index索引。然后通過search搜索Index從而找到我們想要的內容。
首先是創建索引
索引通俗地說就是將內容做成書簽目錄,這樣使得我們能更快地搜索得到內容。對文檔建立好索引后,就可以在這些索引上面進行搜索了。搜索引擎首先會對搜索的關鍵詞進行解析,然后再在建立好的索引上面進行查找,最終返回和用戶輸入的關鍵詞相關聯的文檔。所以創建索引很重要。
五、檢索流程
1. 索引過程:(紅線)
1) 有一系列被索引文件
2) 被索引文件經過語法分析和語言處理形成一系列詞(Term)。
3) 經過索引創建形成詞典和反向索引表。
4) 通過索引存儲將索引寫入硬盤。
2. 搜索過程:(藍線)
a) 用戶輸入查詢語句。(Query)
b) 對查詢語句經過語法分析和語言分析得到一系列詞(Term)。(QueryParser和Analyzer)
c) 通過語法分析得到一個查詢樹。
d) 通過索引存儲將索引讀入到內存。(IndexWriter)
e) 利用查詢樹搜索索引,從而得到每個詞(Term)的文檔鏈表,對文檔鏈表進行交,差,并得
到結果文檔。
f) 將搜索到的結果文檔對查詢的相關性進行排序。
g) 返回查詢結果給用戶。
六、Lucene全文索引引擎與數據庫索
數據庫 |
Lucene全文索引引擎 |
|
索引 |
對于LIKE查詢來說,數據傳統的索引是根本用不上的。數據需要逐個便利記錄進行GREP式的模糊匹配,比有索引的搜索速度要有多個數量級的下降。 |
將數據源中的數據都通過全文索引一一建立反向索引 |
匹配效果 |
使用:like "%net%" 會把netherlands也匹配出來, 多個關鍵詞的模糊匹配:使用like "%com%net%":就不能匹配詞序顛倒的xxx.net..xxx.com |
通過詞元(term)進行匹配,通過語言分析接口的實現,可以實現對中文等非英語的支持。 |
匹配度 |
沒有匹配程度的控制:比如有記錄中net出現5詞和出現1次的,結果是一樣的 |
有匹配度算法,將匹配程度(相似度)比較高的結果排在前面。 |
結果輸出 |
返回所有的結果集,在匹配條目非常多的時候(比如上萬條)需要大量的內存存放這些臨時結果集。 |
通過特別的算法,將最匹配度最高的頭100條結果輸出,結果集是緩沖式的小批量讀取的。 |
可定制性 |
沒有接口或接口復雜,無法定制 |
通過不同的語言分析接口實現,可以方便的定制出符合應用需要的索引規則(包括對中文的支持) |
結論 |
使用率低,模糊匹配規則簡單或者需要模糊查詢的資料量少 |
高負載的模糊查詢應用,需要負責的模糊查詢的規則,索引的資料量比較大 |
七、關于亞洲語言的的切分詞問題(Word Segment)
對于中文來說,全文索引首先還要解決一個語言分析的問題,對于英文來說,語句中單詞之間是天然通過空格分開的,但亞洲語言的中日韓文語句中的字是一個字挨一個,所有,首先要把語句中按“詞”進行索引的話,這個詞如何切分出來就是一個很大的問題。 首先,肯定不能用單個字符作(si-gram)為索引單元,否則查“上海”時,不能讓含有“海上”也匹配。 但一句話:“北京天安門”,計算機如何按照中文的語言習慣進行切分呢? “北京 天安門” 還是“北 京 天安門”?讓計算機能夠按照語言習慣進行切分,往往需要機器有一個比較豐富的詞庫才能夠比較準確的識別出語句中的單詞。 另外一個解決的辦法是采用自動切分算法:將單詞按照2元語法(bigram)方式切分出來,比如: "北京天安門" ==> "北京 京天 天安 安門"。 這樣,在查詢的時候,無論是查詢"北京" 還是查詢"天安門",將查詢詞組按同樣的規則進行切分:"北京","天安安門",多個關鍵詞之間按與"and"的關系組合,同樣能夠正確地映射到相應的索引中。這種方式對于其他亞洲語言:韓文,日文都是通用的。
來自:http://my.oschina.net/u/1169079/blog/288615