目錄 1. Apache Lucene(全文檢索引擎)—創建索引(第一篇):http://www.cnblogs.com/hanyinglong/p/5387816.html 2. Apache Lucene(全文檢索引擎)—搜索(第二篇): 3. Apache Lucene(全文檢索引擎)—分詞器 ...
目錄
1. Apache Lucene(全文檢索引擎)—創建索引(第一篇):http://www.cnblogs.com/hanyinglong/p/5387816.html
2. Apache Lucene(全文檢索引擎)—搜索(第二篇):
3. Apache Lucene(全文檢索引擎)—分詞器(第三篇):
本項目Demo已上傳GitHub,歡迎大家fork下載學習:https://github.com/kencery/Lucene_Compass(項目內部有很詳細的註釋)
1. 發生在我們身邊的搜索?
a. 當我們去淘寶或者京東買東西的時候經常會用到搜索功能,而他們海量的數據都是存儲在資料庫的,那麼程式猿在實現這個搜索功能的時候,是如何實現的呢?使用資料庫的like這時候就變得捉襟見肘,根本不能用了,因為查詢速度會很慢,而用戶不會為了查詢一個東西等待幾十秒或者幾分鐘(正常一個人願意等待的時間大概為3-5秒),這時候該怎麼實現這樣的查詢呢?
b. 而且它們的查詢功能也基本都類似,都是查詢的文本內容,都是相同的查詢方式 ,即找出含有指定字元串的資源。
2. lucene是什麼呢?
a. lucene一個成熟的、開源的、高性能,可伸縮的全文信息搜索庫,它可以使你的引用程式添加索引和搜索能力
a.1 全文檢索:電腦程式通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置,當用戶查詢時根據建立的索引查找,並將查找的結果反饋給用戶的檢索方式,在信息檢索工具中,全文檢索是最具通用性和實用性的。
b. lucenee的作者Doug Cutting將其貢獻給Apache,成為Apache基金的一個子項目(http://jakarta.apache.org/lucene/)
c. 基於lucene開源搜索引擎出現了很多,例如(Apache Solr、Elastic Search、Index Tank、Katta、Bobo Search、Compass、Summa、Summa),它們都是使用lucene來實現的,讓我們能夠感受一下lucene的強大。
d. lucene只關註文本的索引和搜索,不處理語意,搜索時英文不區分大小寫
e. 全文檢索系統結構(從下圖就可以領略到全文檢索的精髓所在)。
f. 關於lucene的Demo地址:https://github.com/kencery/Lucene_Compass(裡面每個分支詳細講解了lucene的功能和實現)。
g. 博客中使用的圖片大部分來源於網路,前輩們畫的已經非常好,看圖就能夠理解了,自認為自己畫的超不過前輩,故而拿來主義了。
3. 為什麼使用lucene全文檢索呢?
a. 假如信息檢索系統在用戶發出了檢索請求後在去資料庫中查找結果,根本無法再有限的時間內返回結果,所有要先把需要檢索的資源放到本地,並且使用某種特定的數據結構存儲,稱為索引,這個索引的集合稱之為索引庫,由於索引庫的結構是按照專門為快速查詢設計的,所以查詢的速度非常快,我們每次搜索都是在本地的索引庫中進行,那麼這時候就出現了數據集合和索引庫的一致性,故而對於全文檢索功能的開發,需要做的有兩個方面:索引庫管理(維護索引庫中的數據)、在索引庫中進行搜索,而Lucene就是操作索引庫的工具。
b. lucene作為一個全文檢索引擎,其具有以下優點:
b.1 索引文件獨立於應用平臺。lucene定義了一套以8位位元組為基礎的索引文件格式,使得相容應用系統和不同平臺都能夠共用建立的索引文件。
b.2 在傳統全文檢索引擎倒排索引的基礎上,實現了分塊索引,能夠針對新的文件建立小文件索引,提升索引速度,然後通過和原來索引的合併,達到優化的目的。
b.3 優秀的面向對象的系統架構,使得對於lucene擴展的學習難度降低,方便擴展新的功能。
b.4 設計了獨立於語言和文件格式的文本分析介面,索引器通過接受Token流完成索引文件的創立,用戶擴展新的語言和文件格式,只需要實現文本分析的介面。
b.5 已經預設實現了一套強大的查詢引擎,用戶無需自己編寫代碼即能夠使系統獲得強大的查詢能力,Lucene查詢實現中預設實現了關鍵字查詢、範圍查詢、查詢所有、通配符查詢、模糊查詢、短語查詢、布爾查詢。
c. 開源,可擴展能力強,有各種語言版本
4. Lucene系統結構以及包結構
a. 系統結構
a.1 lucene的系統由基礎結構封裝,索引核心,對外介面三大部分組成,其中直接操作索引文件的索引核心是整個lucene系統中的重中之重。
b. 包結構
c. Lucene功能強大,但是從根本上來說,還是主要包含兩塊,一是文本內容經切詞後索引入庫,二是根據查詢條件返回結果。
d. 搭建Lucene的開發環境需要加入Lucene的jar包,在項目開發中要加入的jar包至少要有一下幾個:
lucene-core-5.5.0.jar、lucene-analyzers-common-5.5.0.jar、lucene-highlighter-5.5.0.jar、lucene-memory-5.5.0.jar、lucene-queryparser-5.5.0.jar
e. 對索引庫的操作可以分為兩種:管理和查詢,管理索引庫使用IndexWriter,從索引庫中查詢使用IndexSearcher。
5. 理解核心索引類
a. public abstract class org.apache.lucene.store.Directory
Directory類代表lucene索引的位置,它是一個抽象類,其中含有兩個實現,第一個是FSDirectory,它表示一個存儲在文件系統中的索引的位置,第二個是RAMDirectory,它表示一個存儲在記憶體當中的索引的位置。
b. public abstract class org.apache.lucene.analysis.Analyzer
b.1 在一個文檔被索引之前,首先需要對文檔內容進行分詞處理,並且剔除一些冗餘的詞句(例如:a,the,they等),這份工作就是有Analyzer來做的。
b.2 Analyzer類是一個抽象類,它有很多實現,請同時按住Ctrl+T查看。
b.3 針對不同的語言和應用需要選擇適合的Analyzer,Analyzer把分詞後的內容交給IndexWriter來建立索引。
c. public final class org.apache.lucene.index.IndexWriterConfig
在lucene3.X以上版本中,與前幾個版本不同的地方包括了IndexWriter實例的初始化,其中需要用到IndexWriterConfig類,另外從Lucene的API中可以看到目前IndexWriter類最新的構造函數需要用到IndexWriterConfig類。
d. public final class org.apache.lucene.document.Document
d.1 Document文檔類似資料庫中的一條記錄,可以由好幾個欄位(Field)組成,並且欄位可以套用不同的類型
d.2 一個Field代表與這個文檔相關的元數據,元數據如:作者,標題,主題,修改日期等等,分別作為文檔的欄位索引和存儲。
d.3 Document的方法
(1) void add(IndexableField field) 添加一個欄位(Field)到Document中
(2) String get(String name) 從文檔中獲得一個欄位對應的文本。
e. public final class org.apache.lucene.document.TextField
e.1 TextField 對象使用來描述一個文檔的某個屬性的,比如一篇文章的作者和標題,可以用兩TextField對象分別描述。
e.2 Field.Store—>表示Field的存儲方式
(1) NO—>原文不存儲在索引文件中,搜索結果命中後,在根據其他附加屬性如文件的Path,資料庫的主鍵等,重新鏈接打開原文,適合原文內容較大的情況。
(2) YES—>索引文件本來只存儲索引數據,此設計將原文內容直接也存儲在索引文件中,如文章的標題,內容。
f. public class org.apache.lucene.index.IndexWriter
f.1 IndexWriter是在索引過程中的中心組件
f.2 IndexWriter 這個類創建一個新的索引並且添加文檔到一個已有的索引中,你可以把IndexWriter想象成讓你可以對索引進行寫操作的對象,但是不能讓你讀取或搜索。
f.3 IndexWriter不是唯一的用來修改索引的類。
6. 創建一個索引的大致實現
a. 代碼以在github上開源,地址:https://github.com/kencery/Lucene_Compass
b. 在建立索引時,先要把文檔存到索引庫中,還要更新辭彙表。
1 /** 2 3 * 為文章建立索引 4 5 * @throws IOException 6 7 */ 8 9 @Test 10 11 public void testCreateIndex() throws Exception { 12 13 //1 將需要添加的實體構造成實體對象 14 15 Article article=new Article(1, "Lucene是全文檢索框架", 16 17 "全文檢索(Full-Text Retrieval)是指以文本作為檢索對象,找出含有指定辭彙的文本。" + 18 19 "全面、準確和快速是衡量全文檢索系統的關鍵指標。"); 20 21 //2 保存到資料庫(此步驟暫時省略) 22 23 //3 建立索引(lucene) 24 25 Directory directory=FSDirectory.open(Paths.get("./indexDir/")); //索引庫目錄 26 27 Analyzer analyzer=new IKAnalyzer(); //分詞器 28 29 IndexWriterConfig iwc= new IndexWriterConfig(analyzer); 30 31 // >>3.1 將Article轉為Document 32 33 /** Store參數說明 34 35 No 本欄位的原始值不存儲 36 37 YES 本欄位的原始值會存在出在資料庫區中 38 39 如果不存在,則搜索出來的結果中這個欄位的值為null */ 40 41 /** 42 43 * 自Lucene4開始 創建field對象使用不同的類型 只需要指定是否需要保存源數據 不需指定分詞類別 44 45 * 之前版本的寫法如下 46 47 * doc.Add(new Field("id", article.id.ToString(), Field.Store.YES, Field.Index.ANALYZED)); 48 49 */ 50 51 Document doc=new Document(); 52 53 doc.add(new TextField("id", article.getId().toString(), Store.YES)); 54 55 doc.add(new TextField("title", article.getTitle(), Store.YES)); 56 57 doc.add(new TextField("content", article.getContent(), Store.YES)); 58 59 // >>3.2 保存到索引庫中 60 61 IndexWriter indexWriter=new IndexWriter(directory,iwc); 62 63 indexWriter.addDocument(doc); 64 65 indexWriter.close(); //釋放資源 66 67 }
希望大家能從中間學到東西,如有疑問,請留言或者去GitHub上看LuceneDemo或者添加我的QQ,我們共同探討。