1.簡介java
倒排索引源於實際應用中須要根據屬性的值來查找記錄。這種索引表中的每一項都包括一個屬性值和具備該屬性值的各記錄的地址。因爲不是由記錄來肯定屬性值,而是由屬性值來肯定記錄的位置,於是稱爲倒排索引(inverted index)。帶有倒排索引的文件咱們稱爲倒排索引文件,簡稱倒排文件(inverted file)。算法
倒排文件(倒排索引),索引對象是文檔或者文檔集合中的單詞等,用來存儲這些單詞在一個文檔或者一組文檔中的存儲位置,是對文檔或者文檔集合的一種最經常使用的索引機制。架構
搜索引擎的關鍵步驟就是創建倒排索引,倒排索引通常表示爲一個關鍵詞,而後是它的頻度(出現的次數),位置(出如今哪一篇文章或網頁中,及有關的日期,做者等信息),它至關於爲互聯網上幾千億頁網頁作了一個索引,比如一本書的目錄、標籤通常。讀者想看哪個主題相關的章節,直接根據目錄便可找到相關的頁面。沒必要再從書的第一頁到最後一頁,一頁一頁的查找。工具
2.Lucene倒排索引原理性能
Lucerne是一個開放源代碼的高性能的java全文檢索引擎工具包,不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎。目的是爲軟件開發人員提供一個簡單易用的工具包,以方便在目標系統中實現全文檢索的功能,或者以此爲基礎創建起完整的全文檢索引擎。搜索引擎
Lucerne使用的是倒排文件索引結構。該結構及相應的生成算法以下: url
設有兩篇文章1和2:spa
文章1的內容爲:Tom lives in Guangzhou,I live in Guangzhou too. 文章2的內容爲:He once lived in Shanghai.開放源代碼
<1>取得關鍵詞指針
因爲lucene是基於關鍵詞索引和查詢的,首先咱們要取得這兩篇文章的關鍵詞,一般咱們須要以下處理措施:
a.咱們如今有的是文章內容,即一個字符串,咱們先要找出字符串中的全部單詞,即分詞。英文單詞因爲用空格分隔,比較好處理。中文單詞間是連在一塊兒的須要特殊的分詞處理。
b.文章中的」in」, 「once」 「too」等詞沒有什麼實際意義,中文中的「的」「是」等字一般也無具體含義,這些不表明概念的詞能夠過濾掉
c.用戶一般但願查「He」時能把含「he」,「HE」的文章也找出來,因此全部單詞須要統一大小寫。
d.用戶一般但願查「live」時能把含「lives」,「lived」的文章也找出來,因此須要把「lives」,「lived」還原成「live」
e.文章中的標點符號一般不表示某種概念,也能夠過濾掉
在lucene中以上措施由Analyzer類完成。 通過上面處理後,
文章1的全部關鍵詞爲:[tom] [live] [guangzhou] [i] [live] [guangzhou] 文章2的全部關鍵詞爲:[he] [live] [shanghai]
<2>創建倒排索引
有了關鍵詞後,咱們就能夠創建倒排索引了。上面的對應關係是:「文章號」對「文章中全部關鍵詞」。倒排索引把這個關係倒過來,變成: 「關鍵詞」對「擁有該關鍵詞的全部文章號」。
文章1,2通過倒排後變成
關鍵詞 文章號 guangzhou 1 he 2 i 1 live 1,2 shanghai 2 tom 1
一般僅知道關鍵詞在哪些文章中出現還不夠,咱們還須要知道關鍵詞在文章中出現次數和出現的位置,一般有兩種位置:
a.字符位置,即記錄該詞是文章中第幾個字符(優勢是關鍵詞亮顯時定位快);
b.關鍵詞位置,即記錄該詞是文章中第幾個關鍵詞(優勢是節約索引空間、詞組(phase)查詢快),lucene中記錄的就是這種位置。
加上「出現頻率」和「出現位置」信息後,咱們的索引結構變爲:
關鍵詞 文章號[出現頻率] 出現位置 guangzhou 1[2] 3,6 he 2[1] 1 i 1[1] 4 live 1[2] 2,5, 2[1] 2 shanghai 2[1] 3 tom 1[1] 1
以live 這行爲例咱們說明一下該結構:live在文章1中出現了2次,文章2中出現了一次,它的出現位置爲「2,5,2」這表示什麼呢?咱們須要結合文章號和出現頻率來分析,文章1中出現了2次,那麼「2,5」就表示live在文章1中出現的兩個位置,文章2中出現了一次,剩下的「2」就表示live是文章2中第 2個關鍵字。
以上就是lucene索引結構中最核心的部分。咱們注意到關鍵字是按字符順序排列的(lucene沒有使用B樹結構),所以lucene能夠用二元搜索算法快速定位關鍵詞。
<3>實現
實現時,lucene將上面三列分別做爲詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不只保存有每一個關鍵詞,還保留了指向頻率文件和位置文件的指針,經過指針能夠找到該關鍵字的頻率信息和位置信息。
Lucene中使用了field的概念,用於表達信息所在位置(如標題中,文章中,url中),在建索引中,該field信息也記錄在詞典文件中,每一個關鍵詞都有一個field信息(由於每一個關鍵字必定屬於一個或多個field)。
<4>壓縮算法
爲了減少索引文件的大小,Lucene對索引還使用了壓縮技術。
首先,對詞典文件中的關鍵詞進行了壓縮,關鍵詞壓縮爲<前綴長度,後綴>,例如:當前詞爲「阿拉伯語」,上一個詞爲「阿拉伯」,那麼「阿拉伯語」壓縮爲<3,語>。
其次大量用到的是對數字的壓縮,數字只保存與上一個值的差值(這樣能夠減少數字的長度,進而減小保存該數字須要的字節數)。例如當前文章號是16389(不壓縮要用3個字節保存),上一文章號是16382,壓縮後保存7(只用一個字節)。
<5>應用緣由
下面咱們能夠經過對該索引的查詢來解釋一下爲何要創建索引。
假設要查詢單詞 「live」,lucene先對詞典二元查找、找到該詞,經過指向頻率文件的指針讀出全部文章號,而後返回結果。詞典一般很是小,於是,整個過程的時間是毫秒級的。
而用普通的順序匹配算法,不建索引,而是對全部文章的內容進行字符串匹配,這個過程將會至關緩慢,當文章數目很大時,時間每每是沒法忍受的。