在前面概要的了解了lucene的内容下面就深入一下lucene的各個子產品。這裡我們主要深入一下lucene的索引,就是如何建構索引的過程及概念。
從兩個角度比較一下吧,一個是從索引方面,一個是模糊查詢,其實歸為一類的化就是全文檢索的對比。
1、索引的對比
對比項
全文檢索庫(Lucene)
關系型資料庫
核心功能
以文字檢索為主,插入、删除、修改比較麻煩,适合于大文本塊的查詢。
插入、删除、修改十分友善,有專門的SQL指令,但對于大文本塊類型的檢索效率較低。
庫
與資料庫類似,都可以建多個庫,而且各個庫的存儲位置可以不同。
可以建多個庫。一般每個庫都有控制檔案和資料檔案等,比較複雜。
表
沒有嚴格的表的概念,Lucene的表隻是由入庫時的定義字段松散構成
有嚴格的表結構,有主鍵,有字段類型等
記錄
由于沒有嚴格的表的概念,是以記錄展現為一個對象,記錄對應的類是Document。
Record,與表結構對應。
字段
字段類型隻有文本和日期兩種,字段一般不支援運算,更無函數功能,字段對應的類是Field類。
字段類型豐富,功能強大。
查詢結果集
在Lucene裡表示查詢結果集的類是Hits,如hits(doc1,doc2,doc3……)
在JDBC中使用Resultset
2、模糊查詢的對比
Lucene全文檢索
資料庫模糊查詢
索引
将資料源中的資料——建立反向索引,速度較快
無法使用資料庫索引,需要周遊所有記錄進行模糊比對,是以查詢速度有多個數量級的下降
比對效果
通過詞元比對,通過語言分析接口進行關鍵诩拆分,能夠實作對中文的支援
由于是模糊查詢,比對不精确,可能查出無關資訊或漏查資訊
比對度
有比對度算法,将比對度比較高的結果排在前面
沒有比對度算法,一個關鍵詞在記錄中出現多少次結果都是一樣的
結果輸出
通過特别的算法,将比對度最高的頭100條結果輸出,結果集是緩沖式的小批量讀取的,系統開銷較小
傳回所有的結果集,在比對條目非常多的時候需要大量的記憶體存放這些臨時結果集,系統開銷大
可定制性
通過API接口可定制出符合檢索排序需要的排序規則
不可定制
适用情況
高負載的模糊查詢應用,索引資料量比較大,速度要求比較快,比對度要求比較高的情況
使用率低,模糊比對規則的簡單或者需要模糊查詢的資料量少的情況
索引建立的過程可以分為将原始文檔轉換成文本、分析文本、将分析好的文本儲存至索引中這麼幾個過程。
圖:lucene建構索引過程
1、提取文本的過程可以使用我們自己的處理方式也可以使用開源架構Tika來處理。
2、分析文檔這個過程很重要,當我們建立起文檔和域之後,就可以使用IndexWriter對象的addDocument方法将資料傳遞給Lucene進行索引操作了。
3、當輸入資料分析完畢後,就可以将分析的結果寫入到索引檔案中了。Lucene将輸入資料以一種反向索引的資料結構進行存儲。
反向索引源于實際應用中需要根據屬性的值來查找記錄。這種索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的位址。由于不是由記錄來确定屬性值, 而是由屬性值來确定記錄的位置,因而稱為反向索引(inverted index)。帶有反向索引的檔案我們稱為反向索引檔案,簡稱倒排檔案(inverted file)。
也就是說,反向索引并不是回答“一個文檔中包含哪些單詞、詞組”,而是經過優化後回答“哪個文檔中包含這個單詞、詞組”。就是更符合我們的要求和習慣的一種做法。
向索引添加文檔
向索引中添加文檔的方法主要有:
addDocument(Document)——使用預設的分析器添加文檔
addDocument(Document,Analyzer)——使用指定的分析器添加文檔和語彙單元化操作
我們在記憶體中先建立一下索引,然後用測試方法測試一下添加索引的動作。程式結構如下:

View Code
其中testIndexWriter()方法用來核對寫入的文檔數,也就是說我們向索引中加入的Document的數量。
上面程式中ids的數量是2,是以這裡assertEquals()得出的結果也應該是2,兩個結果相同,程式正常執行。
然後我們可以看測試程式testIndexReader()方法是用來得到索引對象并且讀出Document的數量。
删除索引中的文檔
删除索引中的文檔主要有下面幾個方法:
deleteDocuments(Term)——删除指定包含項的文檔
deleteDocuments(Term[ ])——删除包含項數組中的所有文檔
deleteDocuments(Query)——删除比對查詢語句的所有文檔
deleteDocuments(Query[ ])——删除比對查詢數組中的所有文檔
deleteAll()——删除索引中的所有文檔
這兩個方法是确定删除文檔的程式,程式結構如下:

這兩個測試程式都是删除已經建構好的索引并且測試得到的結果。
更新索引中的文檔
其實在lucene中的更新操作就是先删除原來的舊的文檔然後加入新的文檔,也就是如果我們想更新某個文檔中的域的變化,那麼就需要先删除原來的Document,然後再新加入新的Document。
程式結構如下:

在這個程式裡就是先建立新的Document,然後更新舊文檔,最後确認新文檔被索引。
域索引選項
這個主要是控制域文本是否可被搜尋,如何搜尋,具體的幾個選項如下:
Index.ANALYZED——分析指定的文本,就是我們在域中指定的選項,比如文章的标題、正文、摘要等。
Index.NOT_ANALYZED——這個比較适合于精确比對,比如我們要搜尋的是一個固定的電話号碼,有點類似于SQL中的select * from 表 where phoneNum='指定值'。
Index.NO——對應的域值不被索引。
域存儲選項
用來确定是否需要存儲域的真實值,也就是說索引的資訊需不需要恢複。兩個可選值如下:
Store.YES——存儲的值是原始值,也就是說根據索引能夠得到原始的值,适合不太大的域值,太大的話會很消耗記憶體。
Store.NO——不存儲原始值,也就是不能恢複,通常用來索引大塊的域。
多值域
比如你的文檔有一個域表示作者名字,但有時該文檔的作者數不止一個。這時候就需要我們向域中寫入不同的值,就像這樣:

這種方式的處理是被鼓勵和接受的。
如果我們有這樣一個需求,就是對索引的文檔分出主次或者區分出權限比重,那麼使用權重操作就會非常容易的實作這個功能。
給文檔權重
如果我們為公司設計搜尋程式來索引和搜尋公司的E-Mail情況,該程式要求在進行搜尋結果排序時,公司員工的E-Mail比其它E-Mail有更重要的位置,那麼就會用到權重操作。
設定不同的權重因子,程式結構如下:

對公司内部的人員郵件加索引時,預設權重因子設定為1.5,其它的設定為0.1,好了,在搜尋的期間,這些權值高的就會被先搜尋出來。
給域權重
還是上面的例子,如何能使郵件的主題比作者更重要呢,那麼就會用到域權重操作。給文檔權重會預設給文檔中的所有域都進行權重,如果想給域權重,我們需要使用Field的setBoost(float)方法,程式結構如下:

為什麼要單獨出來說這個呢,因為有的時候你可能有這樣的需求,比如你要搜尋的是價格資訊,需要的是一個精度的搜尋,有時候你要搜尋一個長度的範圍或者接收資訊的日期等資訊,這些資訊通常都是預設被索引成數字,也就是說你可能不能找到你想要比對的結果,這時候就需要做一些單獨的的處理,在我們加入Field的時候。
索引數字的程式結構:

索引日期和時間的程式結構:

首先要弄清楚一點,優化索引的目的是為了提高搜尋速度而不是為了提高索引速度。
如何優化呢,這裡簡單的做一下整理:
确認你在使用Lucene的最新版本
盡量使用本地檔案系統
使用更快的硬體裝置,特别是更快的IO裝置
加大你的機器記憶體容量,給Java虛拟機配置設定更多的記憶體
在程式中使用一個唯一的IndexSearch執行個體
當測試搜尋速度時,忽略第一次查詢時間
在搜尋之前調用optimize優化你的索引
考慮使用filters
當然這裡隻是列出了一部分的優化手段,具體的情況還需要根據具體的環境來分析,畢竟滿足需求才是最重要的。
1、在lucene中,鎖機制是與并發性相關的一個主題,在同一時刻隻允許單一程序的所有代碼段中,lucene都建立了基于檔案的鎖,以此來避免誤用 lucene的api造成對索引的損壞。每個索引都有自身的鎖檔案集。鎖檔案放在計算機的臨時目錄中,這個目錄由java的java.io.tmpdir 中的系統屬性所指定。
2、(1)IndexReader的isLocked(Directory)-這個方法可以判斷參數中指定的索引是否已經被上鎖。
(2)IndexReader的unlock(Directory)-手動解鎖,使用它有危險性,因為lucene加鎖有其理由。
<a href="http://files.cnblogs.com/skyme/2_BuildIndex.rar">[源碼下載下傳]</a>
<a href="http://www.cnblogs.com/skyme/archive/2012/07/29/2613970.html">一步一步學lucene——(第一步:概念篇)</a>
<a href="http://www.cnblogs.com/skyme/archive/2012/07/30/2615054.html">一步一步學lucene——(第二步:示例篇)</a>
<a href="http://www.cnblogs.com/skyme/archive/2012/07/31/2616213.html">一步一步學lucene——(第三步:索引篇)</a>
<a href="http://www.cnblogs.com/skyme/archive/2012/08/01/2618341.html">一步一步學lucene——(第四步:搜尋篇)</a>