這一節我們來看看搜尋引擎中最重要的幾個資料結構。
前面我們說過索引包含正向索引和反向索引兩部分,首先我們看看正向索引的結構。
正向索引用來儲存文件的各種屬性,從邏輯上講,正向索引其實就是乙個大陣列,陣列中每個元素就是乙個文件的屬性集合。
如果正向索引是有schema的,那麼它其實就類似乙個關係表或者說二維陣列,縱軸是文件,橫軸是屬性;如果正向索引是schema free的,那麼它就類似乙個map的陣列,每個文件都是乙個map,key是屬性名,value是屬性值。
文件在正向索引這個大陣列中的下標也是有用的,在很多搜尋引擎的實現中,這個下標被稱為文件的邏輯id,叫它id是因為它唯一的標示了某個特定的文件,叫它「邏輯」是因這個id只在這個索引中有意義,而且文件也許有自己的類似於id的屬性,要避免混淆。
建立正向索引的過程極其簡單,只需要在這個大陣列後面追加新的文件即可,每次追加乙個文件就會給這個文件產生乙個新的邏輯id。
在搜尋引擎中,一般不會從正向索引中刪除任何文件,如果需要進行刪除操作,則在每個文件中設立乙個是否刪除的標誌,已刪除的文件置1。
正向索引其實就這麼點東西,下面我們來看看反向索引,這個稍微複雜點。
要實現關鍵字查詢,就必須有乙個可以用關鍵字找到文件的資料結構,所以反向索引邏輯上來說就是乙個字典,key是關鍵字,value就是乙個文件集。
在這裡剛好用上我們之前在正向索引裡產生的邏輯id,因為邏輯id唯一的標示乙個文件,所以反向索引中的文件集就變成了乙個邏輯id的集合,實現中當然沒這麼簡單,我們等下再說複雜的。
當然,如果僅僅使用這樣乙個結構,我們一次只能查詢乙個關鍵字,即便是作為乙個玩具來說功能也太弱了點,下面我們來看看多關鍵字聯合查詢怎麼做。
兩個關鍵字的「聯合」,最簡單的有and和or兩種關係,對於and關係,我們需要將兩個關鍵字對應的結果集取交集;對於or則需要取並集;多個關鍵字只需照此辦理即可。現在我們有乙個實際的問題,那就是每個關鍵字對應的結果集可能超大,對它們求交集並集可能是乙個昂貴的操作,昂貴到無法消受。
從前面說過的邏輯id的產生規則可以知道,邏輯id是由小到大順序產生的,沒有重複,利用這一點我們可以做一些有效的優化。
首先,由於文件是順序進入正向索引的,所以邏輯id在加入反向索引時保持公升序,如果我們能保持這個順序,反向索引中每個關鍵字對應的文件集就變成了乙個有序的線性結構,and和or操作也就變成了兩個有序id鏈的交和並。
回顧一下學校中關於演算法和資料結構的教材,如果我沒記錯的話應該有這樣的作業題,我就不幫大家做作業了。
很多搜素引擎還支援過濾條件,例如日期、**等,最簡單的方法就是,拿到反向索引匹配的結果集後,對其中的每個文件,在正向索引中檢查它們的屬性是否滿足過濾條件,如果滿足則保留,否則丟棄,最後剩下來的就是即匹配了關鍵字又滿足過濾條件的文件。
到目前為止,我們已經實現了乙個最基本的全文搜尋引擎,它可以支援多關鍵字的and/or查詢,還可以支援過濾條件,從功能上來說基本相當於乙個玩具版lucene :d:d
關於正向索引與反向索引
這一節我們來看看搜尋引擎中最重要的幾個資料結構。前面我們說過索引包含正向索引和反向索引兩部分,首先我們看看正向索引的結構。正向索引用來儲存文件的各種屬性,從邏輯上講,正向索引其實就是乙個大陣列,陣列中每個元素就是乙個文件的屬性集合。如果正向索引是有schema的,那麼它其實就類似乙個關係表或者說二維...
正向索引與反向索引(solr)
正向索引 正排索引 正排表是以文件的id為關鍵字,表中記錄文件中每個字的位置資訊,查詢時掃瞄表中每個文件中字的資訊直到找出所有包含查詢關鍵字的文件。正排表結構如圖1所示,這種組織方法在建立索引的時候結構比較簡單,建立比較方便且易於維護 因為索引是基於文件建立的,若是有新的文件加入,直接為該文件建立乙...
正向索引 反向索引 B Tree索引
索引就是為了更快的找出需要的資訊。一般都要進行排序。正向索引 開發出來用來儲存每個文件的單詞的列表。實際上,時間 記憶體 處理器等等資源的限制,技術上正向索引是不能實現的。既 儲存乙個文件中有那些單詞。有多少單詞就有多少列。然後對每一列進行某種排序。反向索引 其中每條記錄,記錄的是乙個單詞都在那些文...