倒排索引是搜索引擎中最為核心的一項(xiàng)技術(shù)之一,可以說是搜索引擎的基石。可以說正是有了倒排索引技術(shù),搜索引擎才能有效率的進(jìn)行數(shù)據(jù)庫查找、刪除等操作。
1. 倒排索引的思想
倒排索引源于實(shí)際應(yīng)用中需要根據(jù)屬性的值來查找記錄。這種索引表中的每一項(xiàng)都包括一個(gè)屬性值和具有該屬性值的各記錄的地址。由于不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置,因而稱為倒排索引(inverted index)。
在搜索引擎中,查詢?cè)~可以切分成若干個(gè)單詞,所以對(duì)于搜索引擎中的倒排索引對(duì)應(yīng)的屬性就是單詞,而對(duì)應(yīng)的記錄就是網(wǎng)頁(也可以廣泛地稱為是文檔)。所以,搜索引擎中的倒排索引是實(shí)現(xiàn)“單詞-文檔矩陣”的一種具體存儲(chǔ)形式,通過倒排索引,可以根據(jù)單詞(屬性)快速獲取包含這個(gè)單詞的文檔列表(記錄)。倒排索引主要由兩個(gè)部分組成:“單詞詞典”和“倒排文件”。
2. “單詞-文檔矩陣”
單詞-文檔矩陣是表達(dá)兩者之間所具有的一種包含關(guān)系的概念模型,圖1展示了其含義。圖1的每列代表一個(gè)文檔,每行代表一個(gè)單詞,打?qū)吹奈恢么戆P(guān)系:

圖1 單詞-文檔矩陣
從縱向即文檔這個(gè)維度來看,每列代表文檔包含了哪些單詞,比如文檔1包含了詞匯1和詞匯4,而不包含其它單詞。從橫向即單詞這個(gè)維度來看,每行代表了哪些文檔包含了某個(gè)單詞。比如對(duì)于詞匯1來說,文檔1和文檔4中出現(xiàn)過單詞1,而其它文檔不包含詞匯1。矩陣中其它的行列也可作此種解讀。
搜索引擎的索引其實(shí)就是實(shí)現(xiàn)“單詞-文檔矩陣”的具體數(shù)據(jù)結(jié)構(gòu)。可以有不同的方式來實(shí)現(xiàn)上述概念模型,比如“倒排索引”、“簽名文件”、“后綴樹”等方式。但是各項(xiàng)實(shí)驗(yàn)數(shù)據(jù)表明,“倒排索引”是實(shí)現(xiàn)單詞到文檔映射關(guān)系的最佳實(shí)現(xiàn)方式。
3. 倒排索引的基本框架
單詞和單詞字典:搜索引擎的通常索引單位是單詞,單詞詞典是由文檔集合中出現(xiàn)過的所有單詞構(gòu)成的字符串集合,單詞詞典內(nèi)每條索引項(xiàng)記載單詞本身的一些信息以及指向“倒排列表”的指針。
倒排列表:倒排列表記載了出現(xiàn)過某個(gè)單詞的所有文檔的文檔列表及單詞在該文檔中出現(xiàn)的位置信息,每條記錄稱為一個(gè)倒排項(xiàng)(Posting)。根據(jù)倒排列表,即可獲知哪些文檔包含某個(gè)單詞。
倒排文件:所有單詞的倒排列表往往順序地存儲(chǔ)在磁盤的某個(gè)文件里,這個(gè)文件即被稱之為倒排文件,倒排文件是存儲(chǔ)倒排索引的物理文件。
搜索引擎中倒排索引大概流程框架:用戶在搜索引擎搜索框輸入查詢?cè)~進(jìn)行搜索時(shí),搜索引擎會(huì)對(duì)查詢?cè)~進(jìn)行切詞以及近義詞匹配等操作,根據(jù)原始查詢?cè)~得到一系列的單詞列表。然后根據(jù)搜索引擎內(nèi)部的字典來查詢每個(gè)單詞對(duì)應(yīng)的倒排列表,從而定位到包含這個(gè)單詞的網(wǎng)頁或者說是文檔。最后搜索引擎根據(jù)特定的網(wǎng)頁排序算法將查詢到的網(wǎng)頁進(jìn)行排序,通過前端將搜索結(jié)果展示給用戶。下圖2為倒排索引的主要流程:

圖2 倒排索引流程框架
4. 單詞字典
其實(shí),我們通過上述倒排索引的流程也可以看出來,倒排索引的關(guān)鍵技術(shù)在于建立單詞字典。
單詞詞典用來維護(hù)文檔集合中出現(xiàn)過的所有單詞的相關(guān)信息,同時(shí)用來記載某個(gè)單詞對(duì)應(yīng)的倒排列表在倒排文件中的位置信息。在支持搜索時(shí),根據(jù)用戶的查詢?cè)~,去單詞詞典里查詢,就能夠獲得相應(yīng)的倒排列表,并以此作為后續(xù)排序的基礎(chǔ)。
對(duì)于一個(gè)規(guī)模很大的文檔集合來說,可能包含幾十萬甚至上百萬的不同單詞,能否快速定位某個(gè)單詞,這直接影響搜索時(shí)的響應(yīng)速度,所以需要高效的數(shù)據(jù)結(jié)構(gòu)來對(duì)單詞詞典進(jìn)行構(gòu)建和查找,常用的數(shù)據(jù)結(jié)構(gòu)包括哈希加鏈表結(jié)構(gòu)(哈希存儲(chǔ)的拉鏈法)和樹形詞典結(jié)構(gòu)。
1)哈希拉鏈法
圖3是這種詞典結(jié)構(gòu)的示意圖。這種詞典結(jié)構(gòu)主要由兩個(gè)部分構(gòu)成:
主體部分是哈希表,每個(gè)哈希表項(xiàng)保存一個(gè)指針,指針指向沖突鏈表,在沖突鏈表里,相同哈希值的單詞形成鏈表結(jié)構(gòu)。之所以會(huì)有沖突鏈表,是因?yàn)閮蓚€(gè)不同單詞獲得相同的哈希值,如果是這樣,在哈希方法里被稱做是一次沖突,可以將相同哈希值的單詞存儲(chǔ)在鏈表里,以供后續(xù)查找。

圖3 哈希拉鏈法詞典結(jié)構(gòu)
在建立索引的過程中,詞典結(jié)構(gòu)也會(huì)相應(yīng)地被構(gòu)建出來。比如在解析一個(gè)新文檔的時(shí)候,對(duì)于某個(gè)在文檔中出現(xiàn)的單詞T,首先利用哈希函數(shù)獲得其哈希值,之后根據(jù)哈希值對(duì)應(yīng)的哈希表項(xiàng)讀取其中保存的指針,就找到了對(duì)應(yīng)的沖突鏈表。如果沖突鏈表里已經(jīng)存在這個(gè)單詞,說明單詞在之前解析的文檔里已經(jīng)出現(xiàn)過。如果在沖突鏈表里沒有發(fā)現(xiàn)這個(gè)單詞,說明該單詞是首次碰到,則將其加入沖突鏈表里。通過這種方式,當(dāng)文檔集合內(nèi)所有文檔解析完畢時(shí),相應(yīng)的詞典結(jié)構(gòu)也就建立起來了。
在響應(yīng)用戶查詢請(qǐng)求時(shí),其過程與建立詞典類似,不同點(diǎn)在于即使詞典里沒出現(xiàn)過某個(gè)單詞,也不會(huì)添加到詞典內(nèi)。以圖3為例,假設(shè)用戶輸入的查詢請(qǐng)求為單詞X,對(duì)這個(gè)單詞進(jìn)行哈希,定位到哈希表內(nèi)的4號(hào)槽,從其保留的指針可以獲得沖突鏈表,依次將單詞X和沖突鏈表內(nèi)的單詞比較,發(fā)現(xiàn)單詞X在沖突鏈表內(nèi),于是找到這個(gè)單詞,之后可以讀出這個(gè)單詞對(duì)應(yīng)的倒排列表來進(jìn)行后續(xù)的工作,如果沒有找到這個(gè)單詞,說明文檔集合內(nèi)沒有任何文檔包含單詞,則搜索結(jié)果為空。
2)樹形結(jié)構(gòu)
B樹(或者B+樹)是另外一種高效查找結(jié)構(gòu),圖1-8是一個(gè) B樹結(jié)構(gòu)示意圖。B樹與哈希方式查找不同,需要字典項(xiàng)能夠按照大小排序(數(shù)字或者字符序),而哈希方式則無須數(shù)據(jù)滿足此項(xiàng)要求。
B樹形成了層級(jí)查找結(jié)構(gòu),中間節(jié)點(diǎn)用于指出一定順序范圍的詞典項(xiàng)目存儲(chǔ)在哪個(gè)子樹中,起到根據(jù)詞典項(xiàng)比較大小進(jìn)行導(dǎo)航的作用,最底層的葉子節(jié)點(diǎn)存儲(chǔ)單詞的地址信息,根據(jù)這個(gè)地址就可以提取出單詞字符串。
5. 倒排索引的實(shí)例
假設(shè)文檔集合包含五個(gè)文檔,每個(gè)文檔內(nèi)容如圖4所示,在圖中最左端一欄是每個(gè)文檔對(duì)應(yīng)的文檔編號(hào)。我們的任務(wù)就是對(duì)這個(gè)文檔集合建立倒排索引。

圖4 文檔集合
中文和英文等語言不同,單詞之間沒有明確分隔符號(hào),所以首先要用分詞系統(tǒng)將文檔自動(dòng)切分成單詞序列。這樣每個(gè)文檔就轉(zhuǎn)換為由單詞序列構(gòu)成的數(shù)據(jù)流,為了系統(tǒng)后續(xù)處理方便,需要對(duì)每個(gè)不同的單詞賦予唯一的單詞編號(hào),同時(shí)記錄下哪些文檔包含這個(gè)單詞,在如此處理結(jié)束后,我們可以得到最簡(jiǎn)單的倒排索引(參考圖3-4)。在圖3-4中,“單詞ID”一欄記錄了每個(gè)單詞的單詞編號(hào),第二欄是對(duì)應(yīng)的單詞,第三欄即每個(gè)單詞對(duì)應(yīng)的倒排列表。比如單詞“谷歌”,其單詞編號(hào)為1,倒排列表為{1,2,3,4,5},說明文檔集合中每個(gè)文檔都包含了這個(gè)單詞。

圖5 簡(jiǎn)單的倒排索引
之所以說圖5所示倒排索引是最簡(jiǎn)單的,是因?yàn)檫@個(gè)索引系統(tǒng)只記載了哪些文檔包含某個(gè)單詞,而事實(shí)上,索引系統(tǒng)還可以記錄除此之外的更多信息。在單詞對(duì)應(yīng)的倒排列表中不僅記錄了文檔編號(hào),還可以記載了單詞頻率信息(TF),即這個(gè)單詞在某個(gè)文檔中的出現(xiàn)次數(shù),之所以要記錄這個(gè)信息,是因?yàn)樵~頻信息在搜索結(jié)果排序時(shí),計(jì)算查詢和文檔相似度是很重要的一個(gè)計(jì)算因子,所以將其記錄在倒排列表中,以方便后續(xù)排序時(shí)進(jìn)行分值計(jì)算 實(shí)用的倒排索引還可以記載更多的信息,圖6所示索引系統(tǒng)除了記錄文檔編號(hào)和單詞頻率信息外,額外記載了兩類信息,即每個(gè)單詞對(duì)應(yīng)的“文檔頻率信息”(對(duì)應(yīng)圖6的第三欄)。

圖6 帶有單詞頻率、文檔頻率和出現(xiàn)位置信息的倒排索引
此外,除了上述信息,還可以在倒排列表中記錄單詞在某個(gè)文檔出現(xiàn)的位置信息。
圖6所示倒排索引已經(jīng)是一個(gè)非常完備的索引系統(tǒng),實(shí)際搜索系統(tǒng)的索引結(jié)構(gòu)基本如此,區(qū)別無非是采取哪些具體的數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)上述邏輯結(jié)構(gòu)。
有了這個(gè)索引系統(tǒng),搜索引擎可以很方便地響應(yīng)用戶的查詢,比如用戶輸入查詢?cè)~“Facebook”,搜索系統(tǒng)查找倒排索引,從中可以讀出包含這個(gè)單詞的文檔,這些文檔就是提供給用戶的搜索結(jié)果,而利用單詞頻率信息、文檔頻率信息即可以對(duì)這些候選搜索結(jié)果進(jìn)行排序,計(jì)算文檔和查詢的相似性,按照相似性得分由高到低排序輸出,最后為用戶展示出搜索結(jié)果。