終於有時間總結點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 謝謝哦~~