Lucene

維基教科書,自由的教學讀本

簡介[編輯]

Lucene最初是由Doug Cutting所撰寫的,是一位資深全文索引/檢索專家,曾經是V-Twin搜尋引擎的主要開發者,後來在Excite擔任高級系統架構設計師,目前從事於一些INTERNET底層架構的研究。他貢獻出Lucene的目標是為各種中小型應用程式加入全文檢索功能。 Lucene提供了一個簡單卻強大的應用程式介面,能夠做全文索引和搜尋,在java裡Lucene是一個成熟的免費開放原始碼工具;就其本身而論,Lucene是現在並且是這幾年,最受歡迎的免費java資訊檢索程式庫。人們經常提到資訊檢索程式庫,就像是搜尋引擎,但是不應該將資訊檢索程式庫與網搜尋引擎相混淆。

如何使用Lucene[編輯]

Step1:Lucene下載完後將裡面的lucene-core-{version}.jar 和lucene-demos-{version}.jar 和 queryparser/lucene-queryparser-{version}.jar 放到

     C:\Program Files\Java\jdk1.5.0_11\jre\lib\ext的目錄下

Step2:將上面的3個.jar的檔案路徑加入到CLASSPATH裡完成上面步驟後就可以在Command line下使用Lucene建立Index以及Search。

建立Index:
在Command line下輸入java org.apache.lucene.demo.IndexFiles {full-path-to-lucene}/src 即可建立Index。

Search:
在建立完Index之後接著輸入java org.apache.lucene.demo.SearchFiles之後會出現Query:字樣接著就可以開始Search。

linux環境, lucene-6.3.0例子:

  1. 取得 lucene-6.3.0.tgz。
  2. 假設id為boy, cd /home/boy;mkdir lucene
  3. cd /home/boy; tar zxf lucene-6.3.0.tgz
  4. export CLASSPATH=/home/boy/lucene-6.3.0/core/lucene-core-6.3.0.jar:/home/boy/lucene-6.3.0/demo/lucene-demo-6.3.0.jar:/home/boy/lucene-6.3.0/queryparser/lucene-queryparser-6.3.0.jar
  5. cd /home/boy;java org.apache.lucene.demo.IndexFiles -docs /home/boy/lucene-6.3.0 將會讀取/home/boy/lucene-6.3.0檔案,建立index在目錄 /home/boy/index。
  6. java org.apache.lucene.demo.SearchFiles之後會出現Query:字樣接著就可以開始Search。

Lucene分詞原理[編輯]

假若有以下2篇文章:

文章1的內容是:Tom lives in Guangzhou,I live in Guangzhou too.

文章2的內容是:He once lived in Shanghai.

Lucene是用關鍵詞索引和搜尋的,所以我們要先取得上面兩篇文章的關鍵詞,步驟如下:

Step1:先找出文章中所有的單字,即分詞,因為英文單字是用空格分隔,所以比較好處理,若是中文分詞需用到特殊的分詞處理。

Step2:把文章中沒有意義的單字濾掉,EX:"in","once","too"等等,在中文中就是,"的","是"等等。

Step3:使用者若查詢"He"時要能把"he","HE"的文章也找出來,所以所有單字需要統一大小寫。

Step4:使用者若查詢"live"時,也要將"lives","lived"的文章找出來所以需要把"lives","lived"還原成"live"。

Step5:文章中的標點符號也可以過濾掉。

以上步驟在Lucene中是由Analyzer來完成的。

文章經過處理後:

文章1的所有關鍵詞為:[tom] [live] [guangzhou] [i] [live] [guangzhou]

文章2的所有關鍵詞為:[he] [live] [shanghai]

有了所有的關鍵詞後,我們就可以開始建立倒排索引了。

上面處理過的文章所對應的關係是:"文章編號","文章中所有的關鍵詞"。

若使用一般的索引結構會如下表所示:

文章編號 出現的關鍵詞 出現次數
1 guangzhou,i,live,tom 1,1,1,1
2 he,live,shanghai 1,1,1

從中可以看出一般索引結構是以文章為標準建立索引結構,也就是說他紀錄的是一篇文章中所有的關鍵詞出現的情況,EX:文章2中he,live,shanghai均出現一次,然而使用者進行搜尋時,都是輸入關鍵字進行搜尋,若用這種索引結構,在查某依關鍵字時往往需要遍及所有的索引,當索引量非常大時,效率會成為一個很大的問題。

而倒排索引會把這關係變成:"關鍵詞","出現關鍵詞的所有文章編號"。

所以索引結構如下表所示:

關鍵詞 出現關鍵詞的所有文章編號
guangzhou 1
he 2
i 1
live 1,2
shanghai 2
tom 1

通常只知道以上資訊是不夠的,我們還需要知道關鍵詞在文章中出現的次數以及位置。

關鍵詞位置有兩種:

符號位置:即紀錄該關鍵詞是在文章中第幾個符號。

關鍵詞位置:即記錄該關鍵詞是在文章中的第幾個關鍵詞。(Lucene所用的)

所以上面的資料加入"出現頻率"和"出現位置"的訊息後,索引結構就如下表所示:

關鍵詞 出現關鍵詞的所有文章編號[出現頻率] 出現位置
guangzhou 1[2] 3,6
he 2[1] 1
i 1[1] 4
live 1[2],2[1] 2,5,2
shanghai 2[1] 3
tom 1[1] 1

以live這行來說明索引結構:live在文章1中出現了2次,在文章2中出現了1次,出現的位置為"2,5,2",也就是說live在文章1中出現了2次,位置分別是"2,5";live在文章2中出現了一次,位置是"2"。

上面就是Lucene索引結構中最核心的部份。我們可以看出關鍵詞是依照符號順序排列的,因此Lucene可以利用二元搜尋法來定位關鍵詞。

實際上Lucene將上面的"關鍵詞","文章編號[出現頻率]","出現位置"分成(辭典文件)Term Dictionary,(頻率文件)frequencies,(位置文件)positions保存。

其中Term Dictionary不只存有每個關鍵詞,還保留了frequencies和positions的指針,透過指針可以找到該關鍵詞的頻率訊息和位置訊息。

Lucene也使用了field的概念,field是用於表達訊息的所在位置(EX:標題中,文章中,url中),在建立索引時field的訊息也被記錄在Term Dictionary中,每一個關鍵詞都有一個field訊息(因為每一個關鍵詞一定屬於一個或多個)。

下面我們將說明為什麼要建立索引(Index):

假設我們查詢"live",Lucene會用二元搜尋法對Term Dictionary做關鍵詞的尋找,找到該關鍵詞後,透過指向frequencies的指針讀出所有的文章編號,然後將找到的文章輸出給使用者。Term Dictionary通常都很小,所以整個過程的時間是毫秒級的。

外部連結[編輯]