當前位置:
首頁 > 最新 > Lucene就是這麼簡單

Lucene就是這麼簡單

什麼是Lucene??

Lucene是apache軟體基金會發布的一個開放源代碼的全文檢索引擎工具包,由資深全文檢索專家Doug Cutting所撰寫,它是一個全文檢索引擎的架構,提供了完整的創建索引和查詢索引,以及部分文本分析的引擎,Lucene的目的是為軟體開發人員提供一個簡單易用的工具包,以方便在目標系統中實現全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎,Lucene在全文檢索領域是一個經典的祖先,現在很多檢索引擎都是在其基礎上創建的,思想是相通的。

Lucene是根據關健字來搜索的文本搜索工具,只能在某個網站內部搜索文本內容,不能跨網站搜索

既然談到了網站內部的搜索,那麼我們就談談我們熟悉的百度、google那些搜索引擎又是基於什麼搜索的呢….

這裡寫圖片描述

這裡寫圖片描述

從圖上已經看得很清楚,baidu、google等搜索引擎其實是通過網路爬蟲的程序來進行搜索的

為什麼我們要用Lucene?

在介紹Lucene的時候,我們已經說了:Lucene又不是搜索引擎,僅僅是在網站內部進行文本的搜索。那我們為什麼要學他呢???

我們之前編寫納稅服務系統的時候,其實就已經使用過SQL來進行站內的搜索..

既然SQL能做的功能,我們還要學Lucene,為什麼呢???

我們來看看我們用SQL來搜索的話,有什麼缺點:

(1)SQL只能針對資料庫表搜索,不能直接針對硬碟上的文本搜索

(2)SQL沒有相關度排名

(3)SQL搜索結果沒有關健字高亮顯示

(4)SQL需要資料庫的支持,資料庫本身需要內存開銷較大,例如:Oracle

(5)SQL搜索有時較慢,尤其是資料庫不在本地時,超慢,例如:Oracle

這裡寫圖片描述

我們來看看在baidu中搜索Lucene為關鍵字搜索出的內容是怎麼樣的:

這裡寫圖片描述

以上所說的,我們如果使用SQL的話,是做不到的。因此我們就學習Lucene來幫我們在站內根據文本關鍵字來進行搜索數據

我們如果網站需要根據關鍵字來進行搜索,可以使用SQL,也可以使用Lucene…那麼我們Lucene和SQL是一樣的,都是在持久層中編寫代碼的。。

這裡寫圖片描述

一、快速入門

接下來,我們就講解怎麼使用Lucene了…..在講解Lucene的API之前,我們首先來講講Lucene存放的究竟是什麼內容…我們的SQL使用的是資料庫中的內存,在硬碟中為DBF文件…那麼我們Lucene內部又是什麼東西呢??

Lucene中存的就是一系列的二進位壓縮文件和一些控制文件,它們位於計算機的硬碟上,

這些內容統稱為索引庫,索引庫有二部份組成:

(1)原始記錄

存入到索引庫中的原始文本,例如:我是鍾福成

(2)辭彙表

按照一定的拆分策略(即分詞器)將原始記錄中的每個字元拆開後,存入一個供將來搜索的表

也就是說:Lucene存放數據的地方我們通常稱之為索引庫,索引庫又分為兩部分組成:原始記錄和辭彙表….

1.1原始記錄和辭彙表

當我們想要把數據存到索引庫的時候,我們首先存入的是將數據存到原始記錄上面去….

又由於我們給用戶使用的時候,用戶使用的是關鍵字來進行查詢我們的具體記錄。因此,我們需要把我們原始存進的數據進行拆分!將拆分出來的數據存進辭彙表中

辭彙表就是類似於我們在學Oracle中的索引表,拆分的時候會給出對應的索引值。

一旦用戶根據關鍵字來進行搜索,那么程序就先去查詢辭彙表中有沒有該關鍵字,如果有該關鍵字就定位到原始記錄表中,將符合條件的原始記錄返回給用戶查看

我們查看以下的圖方便理解:

這裡寫圖片描述

到了這裡,有人可能就會疑問:難道原始記錄拆分的數據都是一個一個漢字進行拆分的嗎??然後在辭彙表中不就有很多的關鍵字了???

其實,我們在存到原始記錄表中的時候,可以指定我們使用哪種演算法來將數據拆分,存到辭彙表中…..我們的圖是Lucene的標準分詞演算法,一個一個漢字進行拆分。我們可以使用別的分詞演算法,兩個兩個拆分或者其他的演算法。

1.2編寫第一個Lucene程序

首先,我們來導入Lucene的必要開發包:

lucene-core-3.0.2.jar【Lucene核心】

lucene-analyzers-3.0.2.jar【分詞器】

lucene-highlighter-3.0.2.jar【Lucene會將搜索出來的字,高亮顯示,提示用戶】

lucene-memory-3.0.2.jar【索引庫優化策略】

創建User對象,User對象封裝了數據….

我們想要使用Lucene來查詢出站內的數據,首先我們得要有個索引庫吧!於是我們先創建索引庫,將我們的數據存到索引庫中

創建索引庫的步驟:

1)創建JavaBean對象

2)創建Docment對象

3)將JavaBean對象所有的屬性值,均放到Document對象中去,屬性名可以和JavaBean相同或不同

4)創建IndexWriter對象

5)將Document對象通過IndexWriter對象寫入索引庫中

6)關閉IndexWriter對象

這裡寫圖片描述

程序執行完,我們就會在硬碟中見到我們的索引庫。

這裡寫圖片描述

那我們現在是不知道記錄是否真真正正存儲到索引庫中的,因為我們看不見。索引庫存放的數據放在cfs文件下,我們也是不能打開cfs文件的

於是,我們現在用一個關鍵字,把索引庫的數據讀取。看看讀取數據是否成功。

根據關鍵字查詢索引庫中的內容:

1)創建IndexSearcher對象

2)創建QueryParser對象

3)創建Query對象來封裝關鍵字

4)用IndexSearcher對象去索引庫中查詢符合條件的前100條記錄,不足100條記錄的以實際為準

5)獲取符合條件的編號

6)用indexSearcher對象去索引庫中查詢編號對應的Document對象

7)將Document對象中的所有屬性取出,再封裝回JavaBean對象中去,並加入到集合中保存,以備將之用

這裡寫圖片描述

效果:

這裡寫圖片描述

1.3進一步說明Lucene代碼

我們的Lucene程序就是大概這麼一個思路:將JavaBean對象封裝到Document對象中,然後通過IndexWriter把document寫入到索引庫中。當用戶需要查詢的時候,就使用IndexSearcher從索引庫中讀取數據,找到對應的Document對象,從而解析裡邊的內容,再封裝到JavaBean對象中讓我們使用

這裡寫圖片描述

二、對Lucene代碼優化

我們再次看回我們上一篇快速入門寫過的代碼,我來截取一些有代表性的:

以下代碼在把數據填充到索引庫,和從索引庫查詢數據的時候,都出現了。是重複代碼

以下的代碼其實就是將JavaBean的數據封裝到Document對象中,我們是可以通過反射來對其進行封裝….如果不封裝的話,我們如果有很多JavaBean都要添加到Document對象中,就會出現很多類似的代碼。

以下代碼就是從Document對象中把數據取出來,封裝到JavaBean去。如果JavaBean中有很多屬性,也是需要我們寫很多次類似代碼….

2.1編寫Lucene工具類

在編寫工具類的時候,值得注意的地方:

當我們得到了對象的屬性的時候,就可以把屬性的get方法封裝起來

得到get方法,就可以調用它,得到對應的值

在操作對象的屬性時,我們要使用暴力訪問

如果有屬性,值,對象這三個變數,我們記得使用BeanUtils組件

2.2使用LuceneUtils改造程序

三、索引庫優化

我們已經可以創建索引庫並且從索引庫讀取對象的數據了。其實索引庫還有地方可以優化的….

3.1合併文件

我們把數據添加到索引庫中的時候,每添加一次,都會幫我們自動創建一個cfs文件

這裡寫圖片描述

這樣其實不好,因為如果數據量一大,我們的硬碟就有非常非常多的cfs文件了…..其實索引庫會幫我們自動合併文件的,默認是10個

如果,我們想要修改默認的值,我們可以通過以下的代碼修改:

3.2設置內存索引庫

我們的目前的程序是直接與文件進行操作,這樣對IO的開銷其實是比較大的。而且速度相對較慢….我們可以使用內存索引庫來提高我們的讀寫效率…

對於內存索引庫而言,它的速度是很快的,因為我們直接操作內存…但是呢,我們要將內存索引庫是要到硬碟索引庫中保存起來的。當我們讀取數據的時候,先要把硬碟索引庫的數據同步到內存索引庫中去的。

這裡寫圖片描述

四、分詞器

我們在前面中就已經說過了,在把數據存到索引庫的時候,我們會使用某些演算法,將原始記錄表的數據存到辭彙表中…..那麼這些演算法總和我們可以稱之為分詞器

分詞器: ** 採用一種演算法,將中英文本中的字元拆分開來,形成辭彙,以待用戶輸入關健字後搜索**

對於為什麼要使用分詞器,我們也明確地說過:由於用戶不可能把我們的原始記錄數據完完整整地記錄下來,於是他們在搜索的時候,是通過關鍵字進行對原始記錄表的查詢….此時,我們就採用分詞器來最大限度地匹配相關的數據

這裡寫圖片描述

4.1分詞器流程

步一:按分詞器拆分出辭彙

步二:去除停用詞和禁用詞

步三:如果有英文,把英文字母轉為小寫,即搜索不分大小寫

4.2分詞器API

我們在選擇分詞演算法的時候,我們會發現有非常非常多地分詞器API,我們可以用以下代碼來看看該分詞器是怎麼將數據分割的

在實驗完之後,我們就可以選擇恰當的分詞演算法了….

4.3IKAnalyzer分詞器

這是一個第三方的分詞器,我們如果要使用的話需要導入對應的jar包

這個第三方的分詞器有什麼好呢????他是中文首選的分詞器…也就是說:他是按照中文的詞語來進行拆分的!

五、對搜索結果進行處理

5.1搜索結果高亮

我們在使用SQL時,搜索出來的數據是沒有高亮的…而我們使用Lucene,搜索出來的內容我們可以設置關鍵字為高亮…這樣一來就更加註重用戶體驗了!

5.2搜索結果摘要

如果我們搜索出來的文章內容太大了,而我們只想顯示部分的內容,那麼我們可以對其進行摘要…

值得注意的是:搜索結果摘要需要與設置高亮一起使用

5.3搜索結果排序

我們搜索引擎肯定用得也不少,使用不同的搜索引擎來搜索相同的內容。他們首頁的排行順序也會不同…這就是它們內部用了搜索結果排序….

影響網頁的排序有非常多種:

head/meta/【keywords關鍵字】

網頁的標籤整潔

網頁執行速度

採用div+css

等等等等

而在Lucene中我們就可以設置相關度得分來使不同的結果對其進行排序:

當然了,我們也可以按單個欄位排序:

也可以按多個欄位排序:在多欄位排序中,只有第一個欄位排序結果相同時,第二個欄位排序才有作用 提倡用數值型排序

5.4條件搜索

在我們的例子中,我們使用的是根據一個關鍵字來對某個欄位的內容進行搜索。語法類似於下面:

其實,我們也可以使用關鍵字來對多個欄位進行搜索,也就是多條件搜索。我們實際中常常用到的是多條件搜索,多條件搜索可以使用我們最大限度匹配對應的數據

六、總結

Lucene是全文索引引擎的祖先,後面的Solr、Elasticsearch都是基於Lucene的(後面會有一篇講Elasticsearch的,敬請期待~)

Lucene中存的就是一系列的二進位壓縮文件和一些控制文件,這些內容統稱為索引庫,索引庫又分了兩個部分:

原始記錄

辭彙表

了解索引庫的優化方式:1、合併文件 2、設置內存索引庫

Lucene的分詞器有非常多種,選擇自己適合的一種進行分詞

查詢出來的結果可對其設置高亮、摘要、排序

這篇這是Lucene的冰山一角,一般現在用的可能都是Solr、Elasticsearch的了,但想要更加深入了解Lucene可翻閱其他資料哦~


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Java3y 的精彩文章:

納稅服務系統二POI、用戶唯一性校驗
Oracle總結視圖、索引、事務、用戶許可權、批量操作

TAG:Java3y |