1. 程式人生 > >《開發自己的搜尋引擎》讀書筆記——索引的建立

《開發自己的搜尋引擎》讀書筆記——索引的建立

11、Segment

在每個segment裡,有許多的Document,在一個索引中,可能有多個segment。Lucene對索引管理的最大單位就是segment。每個segment內的所有索引檔案都具有相同的字首。

在一個索引中,只有一個“segments”檔案,這個檔案沒有後綴,它記錄著當前的索引內有多少個segments,每個segment中有多少個Document這樣的資訊。

12

.fdt檔案是主要的儲存資料來源資料的檔案,.fdx檔案只是記錄下當前Document在.fdt中的位置,以便後面讀取時方便。需要注意,在.fdt檔案中儲存的field的值僅為Document中具有Store.YES屬性的field。

13、Lucene的索引部分invertDocument方法負責了呼叫底層分析器的介面,來對資料來源進行分析,並統計詞條的位置和頻率資訊,然後將其存入postingTable中。

在invertDocument方法中,需要注意:

(1)、對所有需要加入索引的field進行遍歷。對於那些不需要分詞的field,就將其整個field的資料作為一個大詞條,放入postingTable中。

(2)、對於需要分詞的field,則呼叫底層分詞介面進行分詞,然後將每個分出來的詞都放入postingTable中去。

14對postingTable進行排序

所有詞條被加入postingTable後,Lucene首先將這個postingTable轉化為一個Posting型別的陣列,然後對這個陣列進行排序,使所有的詞條按其字典序排列。那樣,就可以將詞條資訊寫入.tii和.tis檔案。另外,將頻率和位置資訊寫入.frq和.prx檔案中去。(在Lucene中採用了快速排序法對這個Posting的陣列進行了排序)。

為什麼Lucene要對Posting的陣列進行排序呢?

這裡涉及一個索引檔案的儲存方式的問題。索引是整個Lucene工作的基礎,沒有索引,搜尋引擎也就失去了意義。那麼,索引檔案的存取和訪問效率就成了制約搜尋引擎效能的重要引數。通常情況下,索引的儲存效率可以比讀取效率略差一些,這是因為,索引的建立時間對使用者體驗並無太大影響,所以,應當建立一種索引格式,使之更有助於加速搜尋程序。這種格式應當具有索引內容少、可進行有序查詢等特點。

15、將Posting資訊寫入索引

16索引檔案格式

(1)、索引的segment

每個segment代表Lucene的一個完整索引段。通常,在一個索引中,會包含有多個segment。每個segment都有統一的字首,這個簽字追的確定是根據當前索引的Document的數量確立的。字首名等於Document數量轉化成36進位制後,在前面加上下劃線而組成。

通常,在一個完整的索引中,有且只有一個“segment”檔案,這個檔案沒有後綴,它記錄了當前索引中所有segment的資訊。

(2).fnm格式的檔案中包含了Document中的所有的field名稱(field name)。

(3).fdx和.fdt是綜合使用的兩個檔案,其中.fdt用於儲存具有Store.YES屬性的field的資料。而.fdx則是一個索引,用於儲存Document在.fdt中的位置。

(4).tis檔案用於儲存分詞後的詞條(Term),而.tii就是它的索引檔案,它標明瞭每個.tis檔案中的詞條的位置。

(5)在Lucene的索引中,所有的文件被刪除後並不是立刻從索引中取出,而是留待下一次合併索引或是對索引進行優化時才真正刪除,這點有點類似於Windows的回收站原理。這種功能是通過deletable檔案實現的。所有的文件在被刪除後,會首先在deletable檔案中留一個記錄,要真正刪除時,才將索引除去。

(6)在IndexWriter中有一個屬性:useCompoundFile,預設值為true,表示是否使用複合索引格式來儲存索引。在索引內容非常大,檔案數量很多的情況下,系統開啟檔案將會極大地耗費系統資源。因此Lucene提供了一種單檔案索引格式,也就是所謂的複合索引格式。使用複合索引格式儲存Document內容時,只需要在初始化完成一個IndexWriter物件後,使用setUseCompoundFile(boolean)方法,將屬性值設定為true就可以了。

17索引過程的調優

(1)合併因子mergeFactor

該因子決定segment該如何被addDocument()方法進行合併。該值取較小時,建索引時需要更小的記憶體,搜尋未優化索引的速度會更快,但索引建立的速度會比較慢,適合於間歇性地向索引加入文件。該值較大時,適合於批量索引建立

舉一個例子:

將mergeFactor的因子設定為10,那麼,每向索引新增10個Document時就會有一個新的segment建立。

當第10個這樣的segment建立好後,它們會被合併成一個具有100個Document的新segment。

接下來,每100個Document又會建立一個新的segment,當第999個文件被加入索引時,此時磁碟上應該已經有了9個segment,其中每個都有100個Document,而第901個到999個Document此時正在記憶體中,還未被寫入磁碟中。

倘若此時再向索引中加入一個Document,那麼,前9個segment就會和這第10個新建立的segment進行合併,成為一個具有1000個Document的segment。過程一次類推。

(2)、maxMergeDocs

該引數用於實現對mergeFactor引數的限制,表示在一個segment中,最多可以擁有的Document數量。

(3)minMergeDocs

當索引被刷到磁碟中,需要首先儲存在記憶體中,minMergeDocs就是用來限制這個記憶體中文件數量的。

18索引的合併與索引的優化

(1)、Directory類有兩個子類:RAMDirectory(與檔案系統的記憶體有關)和FSDirectory(與檔案系統的目錄有關)。

FSDirectory指的是在檔案系統中的一個路徑。因此,當Lucene向其中寫入索引時,會直接寫入到磁碟上。而RAMDirectory則是記憶體中的一個區域,當虛擬機器退出後,裡面的內容會隨之消失。因此需要將RAMDirectory中的內容轉到FSDirectory中。

對於RAMDirectory,只需要簡單的使用建構函式就可以生成例項。而FSDirectory的例項則需要使用靜態方法來生成,這個靜態方法有兩個引數,第一個引數為所需要存入索引的檔案系統的路徑,第二個引數為一個boolean型的引數,表示是否將原目錄中的所有內容清空。

(2)、使用IndexWriter來合併索引

Lucene的IndexWriter類提供了一個介面,以合併不同的索引。這並不是合併具體的目錄,而是合併不同的Directory型物件。不僅可以將存放於不同檔案系統路徑下的索引合併,還可以將記憶體中的索引與檔案系統中的索引合併,以此來儲存那些存放於RAMDirectory中的索引。

在合併記憶體中的索引時,一定要先將相應的IndexWriter關閉,以保證滯留在快取中的文件被“刷”到RAMDirectory中去,這點與使用FSDirectory時一樣,如果不使用close方法關閉IndexWriter,就會發現索引檔案並未真正寫入目錄中去。

(3)、索引的優化

IndexWriter的optimize方法能夠對當前IndexWriter所指定的索引目錄及其所使用的快取目錄下的所有segment做優化,是所有的segments合併成一個完整的segment,即整個索引目錄內只出現一種檔案字首。

19從索引中刪除文件

(1)、在Lucene的index包中,有一個很重要的工具IndexReader。它主要負責對索引的各種讀取和維護工作。如開啟一個索引、取得索引中的某個文件、獲取索引中總文件的數量,甚至從索引中刪除某個文件。

(2)、使用文件ID號來刪除特定文件

方法名IndexReader.deleteDocument(intid)。在Lucene的內部使用類似回收站的機制來管理Document的刪除。在每個Document被從索引中刪除時,它只相當於被扔進了回收站,並未實際刪除,如果不使用reader.close()方法將刪除文件的資訊寫入磁碟,一旦程序退出索引會恢復成原來的狀態。

IndexReader的undeleteAll()方法可以實現反刪除(相當於回收站的還原)。

只需要使用IndexWriter對索引optimize一次,Lucene就會重新為每一個文件分配ID值,這樣,那些被標記為已刪除的Document就真正的被物理刪除了。(清空回收站)。

(3)、使用Field資訊來刪除批量文件

IndexReader的deleteDocument()方法是一個能夠批量刪除索引的方法,它刪除索引是按照詞條來進行的。Term類是用於表示詞條的一個工具,它能夠將詞條表示成<field,value>對。

20、Lucene的同步問題

(1)在Lucene中,對索引發生修改的類主要集中在IndexWriter(主要負責對索引的寫入與索引整體的維護,如合併、優化等操作)和IndexReader(主要負責從索引中刪除文件)。

任一時刻,在系統中只能有一個IndexWriter的例項對索引進行操作,不允許有多個IndexWriter向索引新增Document,或是優化索引、合併segment;

任一時刻,不能有多個IndexReader在執行文件的刪除操作。下一個IndexReader的操作應該在上一個IndexReader的close方法執行未完成後執行;

在使用IndexWriter向索引加入文件前,必須先關閉執行刪除操作的IndexReader例項;

在使用IndexReader刪除前,必須先關閉執行新增Document操作的IndexReader的例項。

(2)Lucene中的鎖

write.lock和commit.lock
21、IndexModifier集成了IndexWriter的大部分功能和IndexReader中的對索引刪除的功能。

相關推薦

開發自己搜尋引擎讀書筆記——索引建立

11、Segment 在每個segment裡,有許多的Document,在一個索引中,可能有多個segment。Lucene對索引管理的最大單位就是segment。每個segment內的所有索引檔案都具有相同的字首。 在一個索引中,只有一個“segments”檔案,這個檔案沒有後綴,它記錄著當前的索引內有多

《JavaScript設計模式與開發實踐》讀書筆記

寫在前面:設計模式這本書讀了一點點,發現這本書並不是死板的去搬運傳統計算機語言的設計模式,而是會結合js特色的行情來加以解讀和拓展,並且在書中所用到的一些程式設計技巧對於平時的開發和學習有很大的借鑑作用。總而言之,這是一本有靈魂的書。所以我打算打打魚,晒晒網,寫點讀

《Spark核心原始碼分析與開發實戰》讀書筆記之一

第1章 Spark系統概述 1.1 Spark是什麼 1. Spark比Hadoop快在哪裡 (1)Spark使用記憶體計算,而Hadoop使用IO (2)Hadoop的計算是按部就班一步一步進行的,而Spark則是提前生成了DAG,優化了運算路徑   1.2 Sp

Android開發藝術探索讀書筆記----View事件體系1

View的概念:View是android中所有控制元件的基類。ViewGroup繼承自View,內部可以有多個控制元件也可以由Viewgroup(譬如LinearLayout) View的位置引數:top:左上角縱座標,left:右上角橫座標,right:右下角橫座標,bo

mongo讀書筆記——索引

索引型別 唯一索引 唯一索引可以確保集合的每一個文件的指定建都有唯一值。例如:如果想保證不同文件的username鍵擁有不同的值,建立一個唯一索引就好了。 db.users.getIndexes() // 檢視所有索引 > db.users.dropIndex(

《effective java》讀書筆記1(建立和銷燬物件)

第1條:考慮用靜態工廠方法代替構造器 1.what is? 此處的靜態工廠方法與設計模式中的工廠模式不一樣。 比如類 class Person{ //A的構造器 public A(){}; //A的靜態工廠方法可以

《AV Foundation 開發祕籍》讀書筆記(一)

第一章 AV Foundation 簡介 1991 年蘋果推出了 Quick Time 首次將數字音訊和數字視訊展現在使用者面前,Quick Time 架構在之後 20 年間給數字多媒體這一領域帶來了變革,對教育、遊戲、娛樂產業的發展影響巨大。但是隨著時間的推

Android開發藝術探索讀書筆記(一)

           首先向各位嚴重推薦主席這本書《Android開發藝術探索》。 再感謝主席邀請寫這篇讀書筆記 + 書評。書已經完整的翻完一遍了,但是還沒有細緻的品讀並run程式碼,最近有時間正好系統的把整本書從內容到程式碼都梳理一遍,一方面方便自己總結,一方面也為主席宣

開發自己搜尋引擎讀書筆記——Lucene搜尋

使用IndexSearcher進行搜尋 Lucene搜尋相關的API多數都被包含在org.apache.lucene.search包中。其中,最重要的是IndexSearcher類。 (1)、Ind

drupal8 模塊開發 讀書筆記 1

影響 反轉 form module uil 例如 hide mac 模塊開發 這個依賴註入有個管理的東西,假設是InjectionManager然後框架,比如說是Framework 現在Framework 想要 實例化一個controller它就問InjectionMana

讀書筆記-MySQL運維內參08-索引實現原理1

復雜 ges ron 神奇 定位 覆蓋 image sql png B樹和B+樹的區別 1,B樹的葉子節點和內節點存在的都是數據行的所有信息,B+樹的內節點值存放鍵(索引)信息,數據都在葉子節點上。 2,由於B樹鍵和值的所有信息,所以每頁的存儲的數據行相對較少,隨數據發

讀書筆記-MySQL運維內參08-索引實現原理2

自己 新節點 .cn 記錄 產生 連接 -m 父節點 alt 我們已經知道B+樹的組織結構及不同層之間是如何關聯的了。 現在我們模擬一個B+樹是如何從小到大,從無到有,從簡到繁的過程。 首先我們來做一些假設: 1,每個頁面包括內節點和葉子節點最多可以

Ngine X 完全開發指南 讀書筆記-前言

功能 做什麽 適合 喜歡 機會 技術分享 gin 系統 模仿   一開始接觸的編程語言是VF,那是一種可視化編程語言,所謂的可視化,就是運行結果能直接看得到的,非常直觀,便於調試,適合剛剛接觸編程的新人學習。當時學得懵懂,半知半解,就是感覺程序非常神奇,常常幾句代碼,幾個單

《python基礎教程》第4章字典:當索引不好用時 讀書筆記

可能 none 存在 讀書筆記 一個 ear PC 類型 隨機   第四章 字典:當索引不好用時 1.通過名字來引用值的數據結構,這種數據結構叫做映射,字典是python中唯一內建的映射類型。 2.len():可以返回字典中的鍵-值對的數量。 3.del 關鍵字也可以刪除字

讀書筆記博客實戰之搜索引擎索引和流量漲跌策略分析[圖]

讀書筆記寫在前面:最近百度動作頻繁,變化十分大,以至於很多網站都出現了流量的大範圍波動,引起了站長們的思考和分析猜測,但通過數據來分析是最可靠的觀點,那麽我們今天就來分析一下這幾天百度在流量漲跌方面有什麽變化吧。實戰分析:讀書筆記博客,主要用於教育類話題的寫作和學習,采用老域名制作的新站,通過該網頁的排名變化

讀書筆記之《高效程式設計師的45個習慣----敏捷開發之道》 摘錄

 讀書筆記之《高效程式設計師的45個習慣----敏捷開發之道》摘錄        此次原創的意思是指這個文章中的內容是由筆者從《高效程式設計師的45個習慣----敏捷開發之道》書中摘錄,而不是別人摘錄的,但是內容並非筆者原創,所摘錄的內容的

文字上的演算法讀書筆記六--搜尋引擎

6 搜尋引擎是什麼玩意兒 Google這家搜尋引擎公司的巨大成功,才把文字處理技術推向了一個新的高度。 6.1 搜尋引擎原理 假設Q為使用者要查詢的關鍵詞;為所有網頁集合中第i個網頁;表示給定一個Q,第i個網頁滿足了使用者需求的概率,那麼搜尋引擎乾的就是根據使用者的輸入Query(也包括

讀書筆記】數學之美2-搜尋引擎

8.簡單之美——布林代數和搜尋引擎 建立一個搜尋引擎大致需要做的幾件事情: 自動下載儘可能多的網頁; 建立快速有效的索引; 根據相關性對網頁進行公平準確的排序。 這就是搜尋的“道”。 關鍵詞=布林運算(詞1,詞2,詞3);接著判斷詞i是否在文獻中,以得到一串二進

INSPIRED啟示錄 讀書筆記 - 第27章 合理運用瀑布式開發方法

瀑布式開發方法的基本原則 1、採用階段式開發:軟體開發過程被事先分成固定的幾個階段,撰寫書面的需求說明文件、設計高層軟體架構、設計低層細節、編寫程式碼、測試、部署 2、採用階段式評審:每個階段結束後,對該階段提交的成果進行評審,評審通過後才能進入下一階段 瀑布式開發方法有正式和非正式兩種形式 1、正式

《Java EE網際網路輕量級框架整合開發讀書筆記

備註:匯入隨書程式碼 剛開始看這本書,第一件事就是把程式碼匯入到eclipse中。 隨書程式碼的目錄結構為: 每一章就是一個工程,比如Chapter2, 如下: 將程式碼匯入到eclipse 分兩個步驟: (1)開啟工程,點選“File”->“Open Project fro