原文鏈接:https://www.cnblogs.com/rodge-run/p/6551152.html
版權(quán)聲明:歡迎分享轉(zhuǎn)載,但請尊重作者勞動成果,轉(zhuǎn)載請注明原文出處(添加原文鏈接)。
一、Lucene產(chǎn)生的背景
數(shù)據(jù)庫中的搜索很容易實現(xiàn),通常都是使用SQL語句進行查詢,而且能很快的得到查詢結(jié)果。
為什么數(shù)據(jù)庫搜索很容易?
因為數(shù)據(jù)庫中的數(shù)據(jù)存儲是有規(guī)律的,有行有列而且數(shù)據(jù)格式、數(shù)據(jù)長度都是固定的。
1.1 數(shù)據(jù)的分類
我們生活中的數(shù)據(jù)總體分為兩種:結(jié)構(gòu)化數(shù)據(jù)和非結(jié)構(gòu)化數(shù)據(jù)。
結(jié)構(gòu)化數(shù)據(jù):指具有固定格式或有限長度的數(shù)據(jù),如數(shù)據(jù)庫,元數(shù)據(jù)等。
非結(jié)構(gòu)化數(shù)據(jù):指不定長或無固定格式的數(shù)據(jù),如郵件,Word文檔等磁盤上的文件。
1.2 非結(jié)構(gòu)化數(shù)據(jù)查詢方法
1.2.1 順序掃描法(Serial Scanning)
所謂順序掃描,比如要找內(nèi)容包含某一個字符串的文件,就是一個文檔一個文檔的看,對于每一個文檔,從頭看到尾,如果此文檔包含此字符串,則此文檔為我們要找的文件,接著看下一個文件,直到掃描完所有的文件。如利用Windows的搜索也可以搜索文件內(nèi)容,只是相當?shù)穆?/p>
1.2.2 全文檢索(Full-text Search)
將非結(jié)構(gòu)化數(shù)據(jù)中的一部分信息提取出來,重新組織,使其變得有一定結(jié)構(gòu),然后對此有一定結(jié)構(gòu)的數(shù)據(jù)進行搜索,從而達到搜索相對較快的目的。這部分從非結(jié)構(gòu)化數(shù)據(jù)中提取出的然后重新組織的信息,我們稱之索引。
例如:字典。字典的拼音表和部首檢字表就相當于字典的索引,對每一個字的解釋是非結(jié)構(gòu)化的,如果字典沒有音節(jié)表和部首檢字表,在茫茫辭海中找一個字只能順序掃描。然而字的某些信息可以提取出來進行結(jié)構(gòu)化處理,比如讀音,就比較結(jié)構(gòu)化,分聲母和韻母,分別只有幾種可以一一列舉,于是將讀音拿出來按一定的順序排列,每一項讀音都指向此字的詳細解釋的頁數(shù)。我們搜索時按結(jié)構(gòu)化的拼音搜到讀音,然后按其指向的頁數(shù),便可找到我們的非結(jié)構(gòu)化數(shù)據(jù) —— 也即對字的解釋。
這種先建立索引,再對索引進行搜索的過程就叫全文檢索(Full-text Search)。
雖然創(chuàng)建索引的過程也是非常耗時的,但是索引一旦創(chuàng)建就可以多次使用,全文檢索主要處理的是查詢,所以耗時間創(chuàng)建索引是值得的。
1.3 如何實現(xiàn)全文檢索
可以使用Lucene實現(xiàn)全文檢索。Lucene是Apache下的一個開放源代碼的全文檢索引擎工具包。提供了完整的查詢引擎和索引引擎,部分文本分析引擎。Lucene的目的是為軟件開發(fā)人員提供一個簡單易用的工具包,以方便的在目標系統(tǒng)中實現(xiàn)全文檢索的功能。
應用場景:對于數(shù)據(jù)量大、數(shù)據(jù)結(jié)構(gòu)不固定的數(shù)據(jù)可采用全文檢索方式搜索,比如百度、Google等搜索引擎、論壇站內(nèi)搜索、電商網(wǎng)站站內(nèi)搜索等。
二、Lucene執(zhí)行原理
2.1 索引和搜索原理

2.1.1 綠色部分
表示索引過程,對要搜索的原始內(nèi)容進行索引構(gòu)建一個索引庫,索引過程包括:
確定原始內(nèi)容即要搜索的內(nèi)容-->采集文檔-->創(chuàng)建文檔-->分析文檔-->索引文檔
2.1.2 紅色表部分
示搜索過程,從索引庫中搜索內(nèi)容,搜索過程包括:
用戶通過搜索界面-->創(chuàng)建查詢-->執(zhí)行搜索,從索引庫搜索-->渲染搜索結(jié)果
2.2 創(chuàng)建索引
對文檔索引的過程,將用戶要搜索的文檔內(nèi)容進行索引,索引存儲在索引庫(index)中。
這里我們要搜索的文檔是磁盤上的文本文件,根據(jù)案例描述:凡是文件名或文件內(nèi)容包括關(guān)鍵字的文件都要找出來,這里要對文件名和文件內(nèi)容創(chuàng)建索引。
2.2.1 獲取原始文檔
原始文檔:是指要索引和搜索的內(nèi)容。原始內(nèi)容包括互聯(lián)網(wǎng)上的網(wǎng)頁(爬蟲)、數(shù)據(jù)庫中的數(shù)據(jù)(sql查詢)、磁盤上的文件(IO流獲?。┑?。
從互聯(lián)網(wǎng)上、數(shù)據(jù)庫、文件系統(tǒng)中等獲取需要搜索的原始信息,這個過程就是信息采集,信息采集的目的是為了對原始內(nèi)容進行索引。
在Internet上采集信息的軟件通常稱為爬蟲或蜘蛛,也稱為網(wǎng)絡機器人,爬蟲訪問互聯(lián)網(wǎng)上的每一個網(wǎng)頁,將獲取到的網(wǎng)頁內(nèi)容存儲起來。
Lucene不提供信息采集的類庫,需要自己編寫一個爬蟲程序?qū)崿F(xiàn)信息采集,也可以通過一些開源軟件實現(xiàn)信息采集,如下:
? ? Nutch(http://lucene.apache.org/nutch),Nutch是Apache的一個子項目,包括大規(guī)模爬蟲工具,能夠抓取和分辨Web網(wǎng)站數(shù)據(jù)。
? ? jsoup(http://jsoup.org/ ),jsoup是一款Java的HTML解析器,可直接解析某個URL地址、HTML文本內(nèi)容。它提供了一套非常省力的API,可通過DOM,CSS以及類似于jQuery的操作方法來取出和操作數(shù)據(jù)。
? ? heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix是一個由Java開發(fā)的、開源的網(wǎng)絡爬蟲,用戶可以使用它來從網(wǎng)上抓取想要的資源。其最出色之處在于它良好的可擴展性,方便用戶實現(xiàn)自己的抓取邏輯。
獲取磁盤上文件的內(nèi)容,可以通過文件流來讀取文本文件的內(nèi)容,對于pdf、doc、xls等文件可通過第三方提供的解析工具讀取文件內(nèi)容,比如Apache POI讀取doc和xls的文件內(nèi)容。
2.2.2 創(chuàng)建文檔對象
獲取原始內(nèi)容的目的是為了索引,在索引前需要將原始內(nèi)容創(chuàng)建成文檔(Document),文檔中包括一個一個的域(Field),域中存儲內(nèi)容。
這里我們可以將磁盤上的一個文件當成一個Document,Document中包括一些Field(file_name文件名稱、file_path文件路徑、file_size文件大小、file_content文件內(nèi)容),如下圖:

注意:每個Document可以有多個Field,不同的Document可以有不同的Field,同一個Document可以有相同的Field(域名和域值都相同)。每個文檔都有一個唯一的編號,就是文檔ID。
2.2.3 分析文檔
將原始內(nèi)容創(chuàng)建為包含域(Field)的文檔(Document),需要再對域中的內(nèi)容進行分析,分析的過程是經(jīng)過對原始文檔提取單詞、將字母轉(zhuǎn)為小寫、去除標點符號、去除停用詞等過程生成最終的語匯單元,可以將語匯單元理解為一個一個的單詞。
比如下面的文檔經(jīng)過分析如下:
原文檔內(nèi)容:
Lucene is a Java full-text search engine.? Lucene is not a complete
application, but rather a code library and API that can easily be used
to add search capabilities to applications.
分析后得到的語匯單元:
lucene、java、full、search、engine。。。。
每個單詞叫做一個Term,不同的域中拆分出來的相同的單詞是不同的Term。Term中包含兩部分:一部分是文檔的域名,另一部分是單詞的內(nèi)容。
例如:文件名中包含apache和文件內(nèi)容中包含的apache是不同的Term。
2.2.4 創(chuàng)建索引
對所有文檔分析得出的語匯單元進行索引,索引的目的是為了搜索,最終要實現(xiàn)只搜索被索引的語匯單元從而找到Document(文檔)。

注意:創(chuàng)建索引是對語匯單元索引,通過詞語找文檔,這種索引的結(jié)構(gòu)叫倒排索引結(jié)構(gòu)。
傳統(tǒng)方法是根據(jù)文件找到該文件的內(nèi)容,再在文件內(nèi)容中匹配搜索關(guān)鍵字,這種方法是順序掃描方法,數(shù)據(jù)量大、搜索慢。
倒排索引結(jié)構(gòu)是根據(jù)內(nèi)容(詞語)找文檔,如下圖:

倒排索引結(jié)構(gòu)也叫反向索引結(jié)構(gòu),包括索引和文檔兩部分,索引即詞匯表,它的規(guī)模較小,而文檔集合較大。
2.3 查詢索引
查詢索引也是搜索的過程。搜索就是用戶輸入關(guān)鍵字,從索引(index)中進行搜索的過程。根據(jù)關(guān)鍵字搜索索引,根據(jù)索引找到對應的文檔,從而找到要搜索的內(nèi)容(這里指磁盤上的文件)。
2.3.1 用戶查詢接口
全文檢索系統(tǒng)提供用戶搜索的界面供用戶提交搜索的關(guān)鍵字,搜索完成展示搜索結(jié)果。
Lucene不提供制作用戶搜索界面的功能,需要根據(jù)自己的需求開發(fā)搜索界面。
2.3.2 創(chuàng)建查詢
用戶輸入查詢關(guān)鍵字執(zhí)行搜索之前需要先構(gòu)建一個查詢對象,查詢對象中可以指定查詢要搜索的Field文檔域、查詢關(guān)鍵字等,查詢對象會生成具體的查詢語法。
例如:語法“fileName:lucene”表示要搜索Field域的內(nèi)容為“l(fā)ucene”的文檔。
2.3.3 執(zhí)行查詢
搜索索引過程:
根據(jù)查詢語法在倒排索引詞典表中分別找出對應搜索詞的索引,從而找到索引所鏈接的文檔鏈表。
例如:搜索語法為“fileName:lucene”表示搜索出fileName域中包含Lucene的文檔。
搜索過程就是在索引上查找域為fileName,并且關(guān)鍵字為lucene的Term,并根據(jù)Term找到文檔ID列表。
2.3.4 渲染結(jié)果
以一個友好的界面將查詢結(jié)果展示給用戶,用戶根據(jù)搜索結(jié)果找自己想要的信息,為了幫助用戶很快找到自己的結(jié)果,提供了很多展示的效果,比如搜索結(jié)果中將關(guān)鍵字高亮顯示,百度提供的快照等。