看Lucene原始碼必須知道的基本概念

程式設計一生發表於2017-04-08

  終於有時間總結點Lucene,雖然是大週末的,已經感覺是對自己的獎勵,畢竟只是喜歡,現在的工作中用不到的。自己看原始碼比較快,看英文原著的技術書也很快。都和語言有很大關係。雖然我們的技術不敢說是部門第一的,說到日語和英語,倒是無人能出其右的。額~~,一個做技術的,感覺自己好弱啊。對語言,只是天賦而已。對技術,卻是痴迷。雖然有人跟我說我不做管理白瞎了我這個人兒。但是我就一心想做技術,如果到了40歲,做技術沒人要的話。我就去矽谷編程式碼去,畢竟矽谷的同事都說我技術挺好的,相信找個技術活兒還是不成問題的。話說現代人確實是比古人努力多了,那鑿壁偷光的匡衡也沒近視,現代不帶眼鏡才是稀有。多情應笑我早生華髮的蘇軾寫《念奴嬌》的時候至少也40歲了吧,現代卻都是少白頭。上班的人不易,公司也不易。所以之前公司晚上8點之後能叫車報銷的時候我也沒打過車,加班餐也不怎麼吃。畢竟我們樂視是一個有理想的公司,大家都是在為理想努力著。樂視不僅是一個生態的企業,而且是個講求創新的企業,在人工智慧方面也是一直領先和執著的。我其實挺看好樂視的前景的,就是,實在話,網際網路技術上比BAT差距挺大的。

     下面的一些基本概念不但有助於看原始碼,在使用像solr這樣的搜尋引擎框架的時候還可以知道自己的配置都做了些什麼事情。我在定義這些概念的時候也都有自己的理解和思考。

  反向索引:全文索引將半結構化或者全文資料進行結構化,儲存為字串到檔案的對映。因為這是一個檔案到字串的反向過程,被稱為反向索引。

  倒排表:上面說的字串到檔案的對映,這個檔案實際上在lucene中是一個文件連結串列,稱為倒排表(Posting List)。

  分片語件(Tokenizer):在呼叫lucene建索引的時候,要先new一個Field,然後新增到Document裡去。這個Field要成為索引的第一步就是進入分片語件進行分詞:Tokenizer主要做了三件事1>分成一個個單獨的單詞 2>取出標點符號 3>去除停用詞(停用詞是沒有實際意義的詞,如:的,兒。每一種語言的分片語件,都有自己的停用詞庫)

  詞元(Token):經過分片語件的三步處理,得到的結果就是詞元了。

  Stemming:對於英語來說,詞元的下一步處理是通過語言處理元件Linguistic Processor來將其變成小寫,然後通過某種演算法將其變成詞根,比如:複數形式變成詞根形式,進行時和完成時變成詞根形式(如果有不知道什麼是詞根的童鞋,可以去問英語老師哦~~)。這種變化過程叫做Stemming。

  Lemmatization:這個也是應用於外語的,如果你做的是中文搜尋,在配置的時候,發現你的搜尋引擎走了這一步,你其實是在無用功哦~~。因為在英語中,有一些複數啊,完成時啊,進行時啊  變化是不規則的,不能通過演算法來解決,就要基於詞典了。這種基於詞典的詞根化過程叫做Lemmatization。但是基於演算法的計算總歸要快於基於匹配的演算法,所以有些其實用Lemmatization也能達到最終效果,但是最好用Stemming。

  詞(Term):經過上面詞根化後的詞成為Term。

  這裡值得注意的是,英語中不管輸入一個單詞的什麼形式,有了詞根化,都可以把帶有各種形式的都搜尋出來。漢語雖然沒有這一步,但是漢語中有近義詞的概念,它的實現和Lemmatization大體相同,都是基於詞典的。但是對它的處理要採用自己配置過濾器的方式。

  索引元件(Indexer):Term要通過Indexer來最終新增到倒排表中。Indexer主要做了兩件事:1>排序 2>合併。最後得到的倒排索引是一個大連結串列,連結串列裡的每個Term都是一個小連結串列,連結串列裡存了在各個文件中出現的詞頻。結構大體是下圖的樣子:

  語法樹:我們輸入的查詢內容是有語法的。在漢語中這種語法體現的不明顯,但在英文中,比如 Lucy AND Lily OR Andy Not Tom就會形成一個由關鍵詞和普通片語成的語法樹,當然語法樹中的單詞也是需要詞根化的。之後,將包含Lucy Lily的連結串列進行取交集(AND操作),得到文件再和包含Andy的合併(OR 操作),再將此連結串列與包含Tom的連結串列進行差(NOT操作),最後對得到的連結串列進行相關度排序,得到結果,語法樹的邏輯上大概長成下面的樣子:

 

  將上面幾個簡單的概念串聯起來其實就是索引和搜尋的過程了。

  索引過程:全文資料經過語法分析和語言處理形成詞(Term),詞再排序和合併成倒排連結串列進行儲存(可以存記憶體,也可以持久化到硬碟)

  搜尋過程:將使用者輸入經過語法分析和語言處理形成詞(Term),通過語法分析得到語法樹,找出所有包含語法樹的詞的文件,進行交,並,差操作得到結果文件,相關度排序得到最終結果。

  

 

  這是一個索引的檔案的磁碟儲存截圖。資料夾下所有檔案構成了lucene的索引(注意後面的檔案大小)。索引中又有些必須知道的概念。

  段(Segment):一個索引可以包含多個段,之間是獨立的,可以合併。具有相同字首的檔案屬於同一個段,圖中顯示了_1s和_b兩個段。segments.gen和segments_1是段的後設資料檔案(儲存屬性的)

  文件(Document)是建索引的基本單位,存在段中。新新增的文件單獨儲存在新生成的段中,隨著段的合併可以將不同的文件合併到同一個段中。

  segments_N檔案:儲存了此索引包含多少個Segment,每個段包含多少Document.

   .fnm檔案:儲存了此段包含了多少field,每個field的名稱及索引方式

  .fdx,.fdt檔案:儲存了此段包含的Document, 每篇Document裡的每個field存了什麼。

  .tvx,.tvd,.tvf檔案:儲存了此段包含多少Document,每篇包含多少Field,每個field包含了多少term,每個term具體資訊。

  .tis,.tii檔案:儲存了此段的Term按字典順序的排序。

  .frq檔案:儲存了倒排表,就是每個Term的文件ID列表。

  .prx檔案:儲存了倒排表中每個詞在包含詞的文件中的位置

  

  困了,碎覺,明天還要早起給男票做早餐~~

 

 如需轉載,請註上我的原文連結:http://www.cnblogs.com/xiexj/p/6679865.html  謝謝哦~~

相關文章