單詞-文檔矩陣是表達二者之間所具備的一種包含關係的概念模型,圖3-1展現了其含義。圖3-1的每列表明一個文檔,每行表明一個單詞,打對勾的位置表明包含關係。html
圖3-1 單詞-文檔矩陣數據結構
從縱向即文檔這個維度來看,每列表明文檔包含了哪些單詞,好比文檔1包含了詞彙1和詞彙4,而不包含其它單詞。從橫向即單詞這個維度來看,每行表明了哪些文檔包含了某個單詞。好比對於詞彙1來講,文檔1和文檔4中出現過單詞1,而其它文檔不包含詞彙1。矩陣中其它的行列也可做此種解讀。ide
搜索引擎的索引其實就是實現「單詞-文檔矩陣」的具體數據結構。能夠有不一樣的方式來實現上述概念模型,好比「倒排索引」、「簽名文件」、「後綴樹」等方式。可是各項實驗數據代表,「倒排索引」是實現單詞到文檔映射關係的最佳實現方式,因此本章主要介紹「倒排索引」的技術細節。函數
文檔(Document):通常搜索引擎的處理對象是互聯網網頁,而文檔這個概念要更寬泛些,表明以文本形式存在的存儲對象,相比網頁來講,涵蓋更多種形式,好比Word,PDF,html,XML等不一樣格式的文件均可以稱之爲文檔。再好比一封郵件,一條短信,一條微博也能夠稱之爲文檔。在本書後續內容,不少狀況下會使用文檔來表徵文本信息。搜索引擎
文檔集合(Document Collection):由若干文檔構成的集合稱之爲文檔集合。好比海量的互聯網網頁或者說大量的電子郵件都是文檔集合的具體例子。指針
文檔編號(Document ID):在搜索引擎內部,會將文檔集合內每一個文檔賦予一個惟一的內部編號,以此編號來做爲這個文檔的惟一標識,這樣方便內部處理,每一個文檔的內部編號即稱之爲「文檔編號」,後文有時會用DocID來便捷地表明文檔編號。htm
單詞編號(Word ID):與文檔編號相似,搜索引擎內部以惟一的編號來表徵某個單詞,單詞編號能夠做爲某個單詞的惟一表徵。對象
倒排索引(Inverted Index):倒排索引是實現「單詞-文檔矩陣」的一種具體存儲形式,經過倒排索引,能夠根據單詞快速獲取包含這個單詞的文檔列表。倒排索引主要由兩個部分組成:「單詞詞典」和「倒排文件」。排序
單詞詞典(Lexicon):搜索引擎的一般索引單位是單詞,單詞詞典是由文檔集合中出現過的全部單詞構成的字符串集合,單詞詞典內每條索引項記載單詞自己的一些信息以及指向「倒排列表」的指針。索引
倒排列表(PostingList):倒排列表記載了出現過某個單詞的全部文檔的文檔列表及單詞在該文檔中出現的位置信息,每條記錄稱爲一個倒排項(Posting)。根據倒排列表,便可獲知哪些文檔包含某個單詞。
倒排文件(Inverted File):全部單詞的倒排列表每每順序地存儲在磁盤的某個文件裏,這個文件即被稱之爲倒排文件,倒排文件是存儲倒排索引的物理文件。
關於這些概念之間的關係,經過圖3-2能夠比較清晰的看出來。
圖3-2 倒排索引基本概念示意圖
倒排索引從邏輯結構和基本思路上來說很是簡單。下面咱們經過具體實例來進行說明,使得讀者可以對倒排索引有一個宏觀而直接的感覺。
假設文檔集合包含五個文檔,每一個文檔內容如圖3-3所示,在圖中最左端一欄是每一個文檔對應的文檔編號。咱們的任務就是對這個文檔集合創建倒排索引。
圖3-3 文檔集合
中文和英文等語言不一樣,單詞之間沒有明確分隔符號,因此首先要用分詞系統將文檔自動切分紅單詞序列。這樣每一個文檔就轉換爲由單詞序列構成的數據流,爲了系統後續處理方便,須要對每一個不一樣的單詞賦予惟一的單詞編號,同時記錄下哪些文檔包含這個單詞,在如此處理結束後,咱們能夠獲得最簡單的倒排索引(參考圖3-4)。在圖3-4中,「單詞ID」一欄記錄了每一個單詞的單詞編號,第二欄是對應的單詞,第三欄即每一個單詞對應的倒排列表。好比單詞「谷歌」,其單詞編號爲1,倒排列表爲{1,2,3,4,5},說明文檔集合中每一個文檔都包含了這個單詞。
圖3-4 簡單的倒排索引
之因此說圖3-4所示倒排索引是最簡單的,是由於這個索引系統只記載了哪些文檔包含某個單詞,而事實上,索引系統還能夠記錄除此以外的更多信息。圖3-5是一個相對複雜些的倒排索引,與圖3-4的基本索引系統比,在單詞對應的倒排列表中不只記錄了文檔編號,還記載了單詞頻率信息(TF),即這個單詞在某個文檔中的出現次數,之因此要記錄這個信息,是由於詞頻信息在搜索結果排序時,計算查詢和文檔類似度是很重要的一個計算因子,因此將其記錄在倒排列表中,以方便後續排序時進行分值計算。在圖3-5的例子裏,單詞「創始人」的單詞編號爲7,對應的倒排列表內容爲:(3:1),其中的3表明文檔編號爲3的文檔包含這個單詞,數字1表明詞頻信息,即這個單詞在3號文檔中只出現過1次,其它單詞對應的倒排列表所表明含義與此相同。
圖3-5 帶有單詞頻率信息的倒排索引
實用的倒排索引還能夠記載更多的信息,圖3-6所示索引系統除了記錄文檔編號和單詞頻率信息外,額外記載了兩類信息,即每一個單詞對應的「文檔頻率信息」(對應圖3-6的第三欄)以及在倒排列表中記錄單詞在某個文檔出現的位置信息。
圖3-6 帶有單詞頻率、文檔頻率和出現位置信息的倒排索引
「文檔頻率信息」表明了在文檔集合中有多少個文檔包含某個單詞,之因此要記錄這個信息,其緣由與單詞頻率信息同樣,這個信息在搜索結果排序計算中是很是重要的一個因子。而單詞在某個文檔中出現的位置信息並不是索引系統必定要記錄的,在實際的索引系統裏能夠包含,也能夠選擇不包含這個信息,之因此如此,由於這個信息對於搜索系統來講並不是必需的,位置信息只有在支持「短語查詢」的時候纔可以派上用場。
以單詞「拉斯」爲例,其單詞編號爲8,文檔頻率爲2,表明整個文檔集合中有兩個文檔包含這個單詞,對應的倒排列表爲:{(3;1;<4>),(5;1;<4>)},其含義爲在文檔3和文檔5出現過這個單詞,單詞頻率都爲1,單詞「拉斯」在兩個文檔中的出現位置都是4,即文檔中第四個單詞是「拉斯」。
圖3-6所示倒排索引已是一個很是完備的索引系統,實際搜索系統的索引結構基本如此,區別無非是採起哪些具體的數據結構來實現上述邏輯結構。
有了這個索引系統,搜索引擎能夠很方便地響應用戶的查詢,好比用戶輸入查詢詞「Facebook」,搜索系統查找倒排索引,從中能夠讀出包含這個單詞的文檔,這些文檔就是提供給用戶的搜索結果,而利用單詞頻率信息、文檔頻率信息便可以對這些候選搜索結果進行排序,計算文檔和查詢的類似性,按照類似性得分由高到低排序輸出,此即爲搜索系統的部份內部流程,具體實現方案本書第五章會作詳細描述。
單詞詞典是倒排索引中很是重要的組成部分,它用來維護文檔集合中出現過的全部單詞的相關信息,同時用來記載某個單詞對應的倒排列表在倒排文件中的位置信息。在支持搜索時,根據用戶的查詢詞,去單詞詞典裏查詢,就可以得到相應的倒排列表,並以此做爲後續排序的基礎。
對於一個規模很大的文檔集合來講,可能包含幾十萬甚至上百萬的不一樣單詞,可否快速定位某個單詞,這直接影響搜索時的響應速度,因此須要高效的數據結構來對單詞詞典進行構建和查找,經常使用的數據結構包括哈希加鏈表結構和樹形詞典結構。
4.1 哈希加鏈表
圖1-7是這種詞典結構的示意圖。這種詞典結構主要由兩個部分構成:
主體部分是哈希表,每一個哈希表項保存一個指針,指針指向衝突鏈表,在衝突鏈表裏,相同哈希值的單詞造成鏈表結構。之因此會有衝突鏈表,是由於兩個不一樣單詞得到相同的哈希值,若是是這樣,在哈希方法裏被稱作是一次衝突,能夠將相同哈希值的單詞存儲在鏈表裏,以供後續查找。
圖1-7 哈希加鏈表詞典結構
在創建索引的過程當中,詞典結構也會相應地被構建出來。好比在解析一個新文檔的時候,對於某個在文檔中出現的單詞T,首先利用哈希函數得到其哈希值,以後根據哈希值對應的哈希表項讀取其中保存的指針,就找到了對應的衝突鏈表。若是衝突鏈表裏已經存在這個單詞,說明單詞在以前解析的文檔裏已經出現過。若是在衝突鏈表裏沒有發現這個單詞,說明該單詞是首次碰到,則將其加入衝突鏈表裏。經過這種方式,當文檔集合內全部文檔解析完畢時,相應的詞典結構也就創建起來了。
在響應用戶查詢請求時,其過程與創建詞典相似,不一樣點在於即便詞典裏沒出現過某個單詞,也不會添加到詞典內。以圖1-7爲例,假設用戶輸入的查詢請求爲單詞3,對這個單詞進行哈希,定位到哈希表內的2號槽,從其保留的指針能夠得到衝突鏈表,依次將單詞3和衝突鏈表內的單詞比較,發現單詞3在衝突鏈表內,因而找到這個單詞,以後能夠讀出這個單詞對應的倒排列表來進行後續的工做,若是沒有找到這個單詞,說明文檔集合內沒有任何文檔包含單詞,則搜索結果爲空。
4.2 樹形結構
B樹(或者B+樹)是另一種高效查找結構,圖1-8是一個 B樹結構示意圖。B樹與哈希方式查找不一樣,須要字典項可以按照大小排序(數字或者字符序),而哈希方式則無須數據知足此項要求。
B樹造成了層級查找結構,中間節點用於指出必定順序範圍的詞典項目存儲在哪一個子樹中,起到根據詞典項比較大小進行導航的做用,最底層的葉子節點存儲單詞的地址信息,根據這個地址就能夠提取出單詞字符串。
圖1-8 B樹查找結構
參考文獻:
《這就是搜索引擎:核心技術詳解》第三章