數據庫中的搜索很容易實現,一般都是使用sql語句進行查詢,並且能很快的獲得查詢結果。java
爲何數據庫搜索很容易?web
由於數據庫中的數據存儲是有規律的,有行有列並且數據格式、數據長度都是固定的。sql
咱們生活中的數據整體分爲兩種:結構化數據和非結構化數據。數據庫
結構化數據:指具備固定格式或有限長度的數據,如數據庫,元數據等。apache
非結構化數據:指不定長或無固定格式的數據,如郵件,word文檔等磁盤上的文件windows
(1)順序掃描法(Serial Scanning)網絡
所謂順序掃描,好比要找內容包含某一個字符串的文件,就是一個文檔一個文檔的看,對於每個文檔,從頭看到尾,若是此文檔包含此字符串,則此文檔爲咱們要找的文件,接着看下一個文件,直到掃描完全部的文件。如利用windows的搜索也能夠搜索文件內容,只是至關的慢。數據結構
(2)全文檢索(Full-text Search)app
將非結構化數據中的一部分信息提取出來,從新組織,使其變得有必定結構,而後對此有必定結構的數據進行搜索,從而達到搜索相對較快的目的。這部分從非結構化數據中提取出的而後從新組織的信息,咱們稱之索引。工具
例如:字典。字典的拼音表和部首檢字表就至關於字典的索引,對每個字的解釋是非結構化的,若是字典沒有音節表和部首檢字表,在茫茫辭海中找一個字只能順序掃描。然而字的某些信息能夠提取出來進行結構化處理,好比讀音,就比較結構化,分聲母和韻母,分別只有幾種能夠一一列舉,因而將讀音拿出來按必定的順序排列,每一項讀音都指向此字的詳細解釋的頁數。咱們搜索時按結構化的拼音搜到讀音,而後按其指向的頁數,即可找到咱們的非結構化數據——也即對字的解釋。
這種先創建索引,再對索引進行搜索的過程就叫全文檢索(Full-text Search)。
雖然建立索引的過程也是很是耗時的,可是索引一旦建立就能夠屢次使用,全文檢索主要處理的是查詢,因此耗時間建立索引是值得的。
可使用Lucene實現全文檢索。Lucene是apache下的一個開放源代碼的全文檢索引擎工具包。提供了完整的查詢引擎和索引引擎,部分文本分析引擎。Lucene的目的是爲軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能。
應用場景:對於數據量大、數據結構不固定的數據可採用全文檢索方式搜索,好比百度、Google等搜索引擎、論壇站內搜索、電商網站站內搜索等。
全文索引和搜索流程圖:
一、綠色表示索引過程,對要搜索的原始內容進行索引構建一個索引庫,索引過程包括:
肯定原始內容即要搜索的內容-->採集文檔-->建立文檔-->分析文檔-->索引文檔
二、紅色表示搜索過程,從索引庫中搜索內容,搜索過程包括:
用戶經過搜索界面-->建立查詢-->執行搜索,從索引庫搜索-->渲染搜索結果
對文檔索引的過程,將用戶要搜索的文檔內容進行索引,索引存儲在索引庫(index)中。
這裏咱們要搜索的文檔是磁盤上的文本文件,根據案例描述:凡是文件名或文件內容包括關鍵字的文件都要找出來,這裏要對文件名和文件內容建立索引。
1) 獲取原始文檔
原始文檔 是指要索引和搜索的內容。原始內容包括互聯網上的網頁(爬蟲)、數據庫中的數據(sql查詢)、磁盤上的文件(IO流獲取)等。
從互聯網上、數據庫、文件系統中等獲取須要搜索的原始信息,這個過程就是信息採集,信息採集的目的是爲了對原始內容進行索引。
在Internet上採集信息的軟件一般稱爲爬蟲或蜘蛛,也稱爲網絡機器人,爬蟲訪問互聯網上的每個網頁,將獲取到的網頁內容存儲起來。
Lucene不提供信息採集的類庫,須要本身編寫一個爬蟲程序實現信息採集,也能夠經過一些開源軟件實現信息採集,以下:
Nutch(http://lucene.apache.org/nutch), Nutch是apache的一個子項目,包括大規模爬蟲工具,可以抓取和分辨web網站數據。
jsoup(http://jsoup.org/ ),jsoup 是一款Java 的HTML解析器,可直接解析某個URL地址、HTML文本內容。它提供了一套很是省力的API,可經過DOM,CSS以及相似於jQuery的操做方法來取出和操做數據。
heritrix(http://sourceforge.net/projects/archive-crawler/files/),Heritrix 是一個由 java 開發的、開源的網絡爬蟲,用戶可使用它來從網上抓取想要的資源。其最出色之處在於它良好的可擴展性,方便用戶實現本身的抓取邏輯。
獲取磁盤上文件的內容,能夠經過文件流來讀取文本文件的內容,對於pdf、doc、xls等文件可經過第三方提供的解析工具讀取文件內容,好比Apache POI讀取doc和xls的文件內容。
2)建立文檔對象
獲取原始內容的目的是爲了索引,在索引前須要將原始內容建立成文檔(Document),文檔中包括一個一個的域(Field),域中存儲內容。
這裏咱們能夠將磁盤上的一個文件當成一個document,Document中包括一些Field(file_name文件名稱、file_path文件路徑、file_size文件大小、file_content文件內容),以下圖:
注意:每一個Document能夠有多個Field,不一樣的Document能夠有不一樣的Field,同一個Document能夠有相同的Field(域名和域值都相同)
每一個文檔都有一個惟一的編號,就是文檔id。
3) 分析文檔
將原始內容建立爲包含域(Field)的文檔(document),須要再對域中的內容進行分析,分析的過程是通過對原始文檔提取單詞、將字母轉爲小寫、去除標點符號、去除停用詞等過程生成最終的語彙單元,能夠將語彙單元理解爲一個一個的單詞。
好比下邊的文檔通過分析以下:
原文檔內容:
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中包含兩部分一部分是文檔的域名,另外一部分是單詞的內容。
例如:文件名中包含apache和文件內容中包含的apache是不一樣的term。
4) 建立索引
對全部文檔分析得出的語彙單元進行索引,索引的目的是爲了搜索,最終要實現只搜索被索引的語彙單元從而找到Document(文檔)。
注意:建立索引是對語彙單元索引,經過詞語找文檔,這種索引的結構叫倒排索引結構。
傳統方法是根據文件找到該文件的內容,在文件內容中匹配搜索關鍵字,這種方法是順序掃描方法,數據量大、搜索慢。
倒排索引結構是根據內容(詞語)找文檔,以下圖:
倒排索引結構也叫反向索引結構,包括索引和文檔兩部分,索引即詞彙表,它的規模較小,而文檔集合較大。
查詢索引也是搜索的過程。搜索就是用戶輸入關鍵字,從索引(index)中進行搜索的過程。根據關鍵字搜索索引,根據索引找到對應的文檔,從而找到要搜索的內容(這裏指磁盤上的文件)。
1) 用戶查詢接口
全文檢索系統提供用戶搜索的界面供用戶提交搜索的關鍵字,搜索完成展現搜索結果。
Lucene不提供製做用戶搜索界面的功能,須要根據本身的需求開發搜索界面。
2) 建立查詢
用戶輸入查詢關鍵字執行搜索以前須要先構建一個查詢對象,查詢對象中能夠指定查詢要搜索的Field文檔域、查詢關鍵字等,查詢對象會生成具體的查詢語法,
例如: 語法 「fileName:lucene」表示要搜索Field域的內容爲「lucene」的文檔
3) 執行查詢
搜索索引過程:
根據查詢語法在倒排索引詞典表中分別找出對應搜索詞的索引,從而找到索引所連接的文檔鏈表。
好比搜索語法爲「fileName:lucene」表示搜索出fileName域中包含Lucene的文檔。
搜索過程就是在索引上查找域爲fileName,而且關鍵字爲Lucene的term,並根據term找到文檔id列表。
4) 渲染結果
以一個友好的界面將查詢結果展現給用戶,用戶根據搜索結果找本身想要的信息,爲了幫助用戶很快找到本身的結果,提供了不少展現的效果,好比搜索結果中將關鍵字高亮顯示,百度提供的快照等。