<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    szhswl
    宋針還的個人空間
    Lucene的概述:

      Lucene(發(fā)音為 ['lusen] )是一個非常優(yōu)秀的開源的全文搜索引擎,我們可以在它的上面開發(fā)出各種全文搜索的應(yīng)用來。Lucene在國外有很高的知名度,現(xiàn)在已經(jīng)是Apache的頂級項目,在國內(nèi),Lucene的應(yīng)用也越來越多。

    Lucene的算法原理:

      Lucene是一個高性能的java全文檢索工具包,它使用的是倒排文件索引結(jié)構(gòu)。該結(jié)構(gòu)及相應(yīng)的生成算法如下:

     0)設(shè)有兩篇文章1和2
       文章1的內(nèi)容為:Tom lives in Guangzhou,I live in Guangzhou too.
       文章2的內(nèi)容為:He once lived in Shanghai.

     1)全文分析:由于lucene是基于關(guān)鍵詞索引和查詢的,首先我們要取得這兩篇文章的關(guān)鍵詞,通常我們需要如下處理措施
      a.我們現(xiàn)在有的是文章內(nèi)容,即一個字符串,我們先要找出字符串中的所有單詞,即分詞。英文單詞由于用空格分隔,比較好處理。中文單詞間是連在一起的需要特殊的分詞處理。
      b.文章中的”in”, “once” “too”等詞沒有什么實際意義,中文中的“的”“是”等字通常也無具體含義,這些不代表概念的詞可以過濾掉
      c.用戶通常希望查“He”時能把含“he”,“HE”的文章也找出來,所以所有單詞需要統(tǒng)一大小寫。
      d.用戶通常希望查“live”時能把含“lives”,“lived”的文章也找出來,所以需要把“lives”,“lived”還原成“live”
      e.文章中的標點符號通常不表示某種概念,也可以過濾掉
     在lucene中以上措施由Analyzer類完成

     經(jīng)過上面處理后
      文章1的所有關(guān)鍵詞為:[tom] [live] [guangzhou] [i] [live] [guangzhou]
      文章2的所有關(guān)鍵詞為:[he] [live] [shanghai]

     2) 倒排索引:有了關(guān)鍵詞后,我們就可以建立倒排索引了。上面的對應(yīng)關(guān)系是:“文章號”對“文章中所有關(guān)鍵詞”。倒排索引把這個關(guān)系倒過來,變成:“關(guān)鍵詞”對“擁有該關(guān)鍵詞的所有文章號”。文章1,2經(jīng)過倒排后變成
    關(guān)鍵詞 文章號
      guangzhou 1
      he 2
      i 1
      live 1,2
      shanghai 2
      tom 1

      通常僅知道關(guān)鍵詞在哪些文章中出現(xiàn)還不夠,我們還需要知道關(guān)鍵詞在文章中出現(xiàn)次數(shù)和出現(xiàn)的位置,通常有兩種位置:a)字符位置,即記錄該詞是文章中第幾個字符(優(yōu)點是關(guān)鍵詞亮顯時定位快);b)關(guān)鍵詞位置,即記錄該詞是文章中第幾個關(guān)鍵詞(優(yōu)點是節(jié)約索引空間、詞組(phase)查詢快),lucene中記錄的就是這種位置。

    加上“出現(xiàn)頻率”和“出現(xiàn)位置”信息后,我們的索引結(jié)構(gòu)變?yōu)椋?nbsp;

     

     

     關(guān)鍵詞  文章號  [出現(xiàn)頻率]  出現(xiàn)位置
     guangzhou  1  [2]  3,6
     he  2  [1]  1
     i  1  [1]  4
     live  1  [2]  2,5
       2  [1]  2
     shanghai  2  [1]  3
     tom  1  [1]  1

     

     

     

     

     

     

     

     

     

     

     

     

     

     

      以live 這行為例我們說明一下該結(jié)構(gòu):live在文章1中出現(xiàn)了2次,文章2中出現(xiàn)了一次,它的出現(xiàn)位置為“2,5,2”這表示什么呢?我們需要結(jié)合文章號和出現(xiàn)頻率來分析,文章1中出現(xiàn)了2次,那么“2,5”就表示live在文章1中出現(xiàn)的兩個位置,文章2中出現(xiàn)了一次,剩下的“2”就表示live是文章2中第 2個關(guān)鍵字。
      以上就是lucene索引結(jié)構(gòu)中最核心的部分。我們注意到關(guān)鍵字是按字符順序排列的(lucene沒有使用B樹結(jié)構(gòu)),因此lucene可以用二元搜索算法快速定位關(guān)鍵詞。
      實現(xiàn)時 lucene將上面三列分別作為詞典文件(Term Dictionary)、頻率文件(frequencies)、位置文件 (positions)保存。其中詞典文件不僅保存有每個關(guān)鍵詞,還保留了指向頻率文件和位置文件的指針,通過指針可以找到該關(guān)鍵字的頻率信息和位置信息。

      Lucene中使用了field的概念,用于表達信息所在位置(如標題中,文章中,url中),在建索引中,該field信息也記錄在詞典文件中,每個關(guān)鍵詞都有一個field信息(因為每個關(guān)鍵字一定屬于一個或多個field)。
      為了減小索引文件的大小,Lucene對索引還使用了壓縮技術(shù)。首先,對詞典文件中的關(guān)鍵詞進行了壓縮,關(guān)鍵詞壓縮為<前綴長度,后綴>,例如:當前詞為“阿拉伯語”,上一個詞為“阿拉伯”,那么“阿拉伯語”壓縮為<3,語>。其次大量用到的是對數(shù)字的壓縮,數(shù)字只保存與上一個值的差值(這樣可以減小數(shù)字的長度,進而減少保存該數(shù)字需要的字節(jié)數(shù))。例如當前文章號是16389(不壓縮要用3個字節(jié)保存),上一文章號是16382,壓縮后保存7(只用一個字節(jié))。 注意是“上一個詞”。由于詞典是按順序排列的,這種壓縮方法的效果會非常顯著。

      下面我們可以通過對該索引的查詢來解釋一下為什么要建立索引。
    假設(shè)要查詢單詞 “live”,lucene先對詞典二元查找、找到該詞,通過指向頻率文件的指針讀出所有文章號,然后返回結(jié)果。詞典通常非常小,因而,整個過程的時間是毫秒級的。
    而用普通的順序匹配算法,不建索引,而是對所有文章的內(nèi)容進行字符串匹配,這個過程將會相當緩慢,當文章數(shù)目很大時,時間往往是無法忍受的。

    全文檢索框架的實現(xiàn)機制:

      Lucene的API接口設(shè)計的比較通用,輸入輸出結(jié)構(gòu)都很像數(shù)據(jù)庫的表==>記錄==>字段,所以很多傳統(tǒng)的應(yīng)用的文件、數(shù)據(jù)庫等都可以比較方便的映射到Lucene的存儲結(jié)構(gòu)/接口中。總體上看:可以先把Lucene當成一個支持全文索引的數(shù)據(jù)庫系統(tǒng)。

    比較一下Lucene和數(shù)據(jù)庫:

     

     Lucene  數(shù)據(jù)庫

     索引數(shù)據(jù)源:doc(field1,field2...) doc(field1,field2...) 

                \  indexer /
            _____________
            | Lucene Index |
                --------------
               / searcher \

    結(jié)果輸出:Hits(doc(field1,field2) doc(field1...))

     索引數(shù)據(jù)源:record(field1,field2...) record(field1..)  

                \  SQL: insert/ 
              _____________
               |   DB  Index   |
                   ------------- 
                / SQL: select \

    結(jié)果輸出:results(record(field1,field2..) record(field1...))

     Document:一個需要進行索引的“單元,一個Document由多個字段組成

     Record:記錄,包含多個字段

    Field:字段

    Field:字段

    Hits:查詢結(jié)果集,由匹配的Document組成

     RecordSet:查詢結(jié)果集,由多個Record組成

    全文檢索 ≠ like "%keyword%"

      由于數(shù)據(jù)庫索引不是為全文索引設(shè)計的,因此,使用like "%keyword%"時,數(shù)據(jù)庫索引是不起作用的,在使用like查詢時,搜索過程又變成類似于一頁頁翻書的遍歷過程了,所以對于含有模糊查詢的數(shù)據(jù)庫服務(wù)來說,LIKE對性能的危害是極大的。如果是需要對多個關(guān)鍵詞進行模糊匹配:like"%keyword1%" and like "%keyword2%" ...其效率也就可想而知了。

      通常比較厚的書籍后面常常附關(guān)鍵詞索引表(比如:北京:12, 34頁,上海:3,77頁……),它能夠幫助讀者比較快地找到相關(guān)內(nèi)容的頁碼。而數(shù)據(jù)庫索引能夠大大提高查詢的速度原理也是一樣,想像一下通過書后面的索引查找的速度要比一頁一頁地翻內(nèi)容高多少倍……而索引之所以效率高,另外一個原因是它是排好序的。對于檢索系統(tǒng)來說核心是一個排序問題。

      所以建立一個高效檢索系統(tǒng)的關(guān)鍵是建立一個類似于科技索引一樣的反向索引機制,將數(shù)據(jù)源(比如多篇文章)排序順序存儲的同時,有另外一個排好序的關(guān)鍵詞列表,用于存儲關(guān)鍵詞==>文章映射關(guān)系,利用這樣的映射關(guān)系索引:[關(guān)鍵詞==>出現(xiàn)關(guān)鍵詞的文章編號,出現(xiàn)次數(shù)(甚至包括位置:起始偏移量,結(jié)束偏移量),出現(xiàn)頻率],檢索過程就是把模糊查詢變成多個可以利用索引的精確查詢的邏輯組合的過程。從而大大提高了多關(guān)鍵詞查詢的效率,所以,全文檢索問題歸結(jié)到最后是一個排序問題。

      由此可以看出模糊查詢相對數(shù)據(jù)庫的精確查詢是一個非常不確定的問題,這也是大部分數(shù)據(jù)庫對全文檢索支持有限的原因。Lucene最核心的特征是通過特殊的索引結(jié)構(gòu)實現(xiàn)了傳統(tǒng)數(shù)據(jù)庫不擅長的全文索引機制,并提供了擴展接口,以方便針對不同應(yīng)用的定制。

      可以通過一下表格對比一下數(shù)據(jù)庫的模糊查詢:

     

       Lucene全文索引引擎  數(shù)據(jù)庫
     索引  將數(shù)據(jù)源中的數(shù)據(jù)都通過全文索引一一建立反向索引  對于LIKE查詢來說,數(shù)據(jù)傳統(tǒng)的索引是根本用不上的。數(shù)據(jù)需要逐個便利記錄進行GREP式的模糊匹配,比有索引的搜索速度要有多個數(shù)量級的下降。
     匹配效果  通過詞元(term)進行匹配,通過語言分析接口的實現(xiàn),可以實現(xiàn)對中文等非英語的支持。  使用:like "%net%" 會把netherlands也匹配出來,
    多個關(guān)鍵詞的模糊匹配:使用like "%com%net%":就不能匹配詞序顛倒的xxx.net..xxx.com
     匹配度  有匹配度算法,將匹配程度(相似度)比較高的結(jié)果排在前面。  沒有匹配程度的控制:比如有記錄中net出現(xiàn)5詞和出現(xiàn)1次的,結(jié)果是一樣的
     結(jié)果輸出  通過特別的算法,將最匹配度最高的頭100條結(jié)果輸出,結(jié)果集是緩沖式的小批量讀取的。  返回所有的結(jié)果集,在匹配條目非常多的時候(比如上萬條)需要大量的內(nèi)存存放這些臨時結(jié)果集。
     可定制性  通過不同的語言分析接口實現(xiàn),可以方便的定制出符合應(yīng)用需要的索引規(guī)則(包括對中文的支持)  沒有接口或接口復(fù)雜,無法定制
     結(jié)論  高負載的模糊查詢應(yīng)用,需要負責的模糊查詢的規(guī)則,索引的資料量比較大  使用率低,模糊匹配規(guī)則簡單或者需要模糊查詢的資料量少

    全文檢索和數(shù)據(jù)庫應(yīng)用最大的不同在于:讓最相關(guān)的 頭100條結(jié)果滿足98%以上用戶的需求。
    Lucene的創(chuàng)新之處:

      大部分的搜索(數(shù)據(jù)庫)引擎都是用B樹結(jié)構(gòu)來維護索引,索引的更新會導(dǎo)致大量的IO操作,Lucene在實現(xiàn)中,對此稍微有所改進:不是維護一個索引文件,而是在擴展索引的時候不斷創(chuàng)建新的索引文件,然后定期的把這些新的小索引文件合并到原先的大索引中(針對不同的更新策略,批次的大小可以調(diào)整),這樣在不影響檢索的效率的前提下,提高了索引的效率。

    Lucene和其他一些全文檢索系統(tǒng)/應(yīng)用的比較:

     

       Lucene  其他開源全文檢索系統(tǒng)
     增量索引和批量索引  可以進行增量的索引(Append),可以對于大量數(shù)據(jù)進行批量索引,并且接口設(shè)計用于優(yōu)化批量索引和小批量的增量索引。  很多系統(tǒng)只支持批量的索引,有時數(shù)據(jù)源有一點增加也需要重建索引。
     數(shù)據(jù)源  Lucene沒有定義具體的數(shù)據(jù)源,而是一個文檔的結(jié)構(gòu),因此可以非常靈活的適應(yīng)各種應(yīng)用(只要前端有合適的轉(zhuǎn)換器把數(shù)據(jù)源轉(zhuǎn)換成相應(yīng)結(jié)構(gòu))。  很多系統(tǒng)只針對網(wǎng)頁,缺乏其他格式文檔的靈活性。
     索引內(nèi)容抓取  Lucene的文檔是由多個字段組成的,甚至可以控制那些字段需要進行索引,那些字段不需要索引,近一步索引的字段也分為需要分詞和不需要分詞的類型:
       需要進行分詞的索引,比如:標題,文章內(nèi)容字段
       不需要進行分詞的索引,比如:作者/日期字段
     缺乏通用性,往往將文檔整個索引了
     語言分析  通過語言分析器的不同擴展實現(xiàn):
    可以過濾掉不需要的詞:an the of 等,
    西文語法分析:將jumps jumped jumper都歸結(jié)成jump進行索引/檢索
    非英文支持:對亞洲語言,阿拉伯語言的索引支持
     缺乏通用接口實現(xiàn)
     查詢分析  通過查詢分析接口的實現(xiàn),可以定制自己的查詢語法規(guī)則:
    比如: 多個關(guān)鍵詞之間的 + - and or關(guān)系等
     功能較強大
     并發(fā)訪問  能夠支持多用戶的使用  功能較強大

    關(guān)于亞洲語言的的切分詞問題(Word Segment)
      對于中文來說,全文索引首先還要解決一個語言分析的問題,對于英文來說,語句中單詞之間是天然通過空格分開的,但亞洲語言的中日韓文語句中的字是一個字挨一個,所有,首先要把語句中按“詞”進行索引的話,這個詞如何切分出來就是一個很大的問題。
      首先,肯定不能用單個字符作(si-gram)為索引單元,否則查“上海”時,不能讓含有“海上”也匹配。
    但一句話:“北京天安門”,計算機如何按照中文的語言習慣進行切分呢?
      “北京 天安門” 還是“北 京 天安門”?讓計算機能夠按照語言習慣進行切分,往往需要機器有一個比較豐富的詞庫才能夠比較準確的識別出語句中的單詞。
      另外一個解決的辦法是采用自動切分算法:將單詞按照2元語法(bigram)方式切分出來,比如:
        "北京天安門" ==> "北京 京天 天安 安門"。
    這樣,在查詢的時候,無論是查詢"北京" 還是查詢"天安門",將查詢詞組按同樣的規(guī)則進行切分:"北京","天安安門",多個關(guān)鍵詞之間按與"and"的關(guān)系組合,同樣能夠正確地映射到相應(yīng)的索引中。這種方式對于其他亞洲語言:韓文,日文都是通用的。
      基于自動切分的最大優(yōu)點是沒有詞表維護成本,實現(xiàn)簡單,缺點是索引效率低,但對于中小型應(yīng)用來說,基于2元語法的切分還是夠用的。基于2元切分后的索引一般大小和源文件差不多,而對于英文,索引文件一般只有原文件的30%-40%不同。

       自動切分  詞表切分
     實現(xiàn)  實現(xiàn)非常簡單  實現(xiàn)復(fù)雜
     查詢  增加了查詢分析的復(fù)雜程度  適于實現(xiàn)比較復(fù)雜的查詢語法規(guī)則
     存儲效率  索引冗余大,索引幾乎和原文一樣大  索引效率高,為原文大小的30%左右
     維護成本  無詞表維護成本  詞表維護成本非常高:中日韓等語言需要分別維護。
    還需要包括詞頻統(tǒng)計等內(nèi)容
     適用領(lǐng)域  嵌入式系統(tǒng):運行環(huán)境資源有限
    分布式系統(tǒng):無詞表同步問題
    多語言環(huán)境:無詞表維護成本
     對查詢和存儲效率要求高的專業(yè)搜索引擎

    目前比較大的搜索引擎的語言分析算法一般是基于以上2個機制的結(jié)合。關(guān)于中文的語言分析算法,大家可以在Google查關(guān)鍵詞"wordsegment search"能找到更多相關(guān)的資料。

    Lucene的結(jié)構(gòu)框架:
      注意:Lucene中的一些比較復(fù)雜的詞法分析是用JavaCC生成的(JavaCC:JavaCompilerCompiler,純Java的詞法分析生成器),所以如果從源代碼編譯或需要修改其中的QueryParser、定制自己的詞法分析器,還需要從https://javacc.dev.java.net/下載javacc。
      lucene的組成結(jié)構(gòu):對于外部應(yīng)用來說索引模塊(index)和檢索模塊(search)是主要的外部應(yīng)用入口。

     org.apache.Lucene.search/  搜索入口
     org.apache.Lucene.index/  索引入口
     org.apache.Lucene.analysis/  語言分析器
     org.apache.Lucene.queryParser/ 查詢分析器
     org.apache.Lucene.document/  存儲結(jié)構(gòu)
     org.apache.Lucene.store/   底層IO/存儲結(jié)構(gòu)
     org.apache.Lucene.util/  一些公用的數(shù)據(jù)結(jié)構(gòu)

    從Lucene學(xué)到更多:
      Luene的確是一個面對對象設(shè)計的典范。

    1. 所有的問題都通過一個額外抽象層來方便以后的擴展和重用:你可以通過重新實現(xiàn)來達到自己的目的,而對其他模塊而不需要;
    2. 簡單的應(yīng)用入口Searcher, Indexer,并調(diào)用底層一系列組件協(xié)同的完成搜索任務(wù);
    3. 所有的對象的任務(wù)都非常專一:比如搜索過程:QueryParser分析將查詢語句轉(zhuǎn)換成一系列的精確查詢的組合(Query),通過底層的索引讀取結(jié)構(gòu)IndexReader進行索引的讀取,并用相應(yīng)的打分器給搜索結(jié)果進行打分/排序等。所有的功能模塊原子化程度非常高,因此可以通過重新實現(xiàn)而不需要修改其他模塊。 
    4. 除了靈活的應(yīng)用接口設(shè)計,Lucene還提供了一些適合大多數(shù)應(yīng)用的語言分析器實現(xiàn)(SimpleAnalyser,StandardAnalyser),這也是新用戶能夠很快上手的重要原因之一。


    這些優(yōu)點都是非常值得在以后的開發(fā)中學(xué)習借鑒的。作為一個通用工具包,Lunece的確給予了需要將全文檢索功能嵌入到應(yīng)用中的開發(fā)者很多的便利。
      此外,通過對Lucene的學(xué)習和使用,我也更深刻地理解了為什么很多數(shù)據(jù)庫優(yōu)化設(shè)計中要求,比如:

    1. 盡可能對字段進行索引來提高查詢速度,但過多的索引會對數(shù)據(jù)庫表的更新操作變慢,而對結(jié)果過多的排序條件,實際上往往也是性能的殺手之一。
    2. 很多商業(yè)數(shù)據(jù)庫對大批量的數(shù)據(jù)插入操作會提供一些優(yōu)化參數(shù),這個作用和索引器的merge_factor的作用是類似的。
    3. 20%/80%原則:查的結(jié)果多并不等于質(zhì)量好,尤其對于返回結(jié)果集很大,如何優(yōu)化這頭幾十條結(jié)果的質(zhì)量往往才是最重要的。
    4. 盡可能讓應(yīng)用從數(shù)據(jù)庫中獲得比較小的結(jié)果集,因為即使對于大型數(shù)據(jù)庫,對結(jié)果集的隨機訪問也是一個非常消耗資源的操作。

    本文轉(zhuǎn)自:http://www.chedong.com/tech/lucene.html



    ---------------------------------------------------------------------------------------------------------------------------------
    說人之短,乃護己之短。夸己之長,乃忌人之長。皆由存心不厚,識量太狹耳。能去此弊,可以進德,可以遠怨。
    http://m.tkk7.com/szhswl
    ------------------------------------------------------------------------------------------------------ ----------------- ---------
    posted on 2007-12-06 15:57 宋針還 閱讀(319) 評論(0)  編輯  收藏 所屬分類: 搜索引擎
    主站蜘蛛池模板: a视频在线免费观看| 最近免费中文字幕mv电影| 亚洲精品亚洲人成人网| 亚欧在线精品免费观看一区| 亚洲熟妇无码一区二区三区| 亚洲精品一级无码中文字幕| 免费无码又爽又刺激高潮视频| 天堂亚洲国产中文在线| 亚洲片一区二区三区| 四虎在线免费视频| 羞羞网站在线免费观看| 亚洲一区免费观看| 午夜国产羞羞视频免费网站| 香蕉免费一区二区三区| 激情吃奶吻胸免费视频xxxx| 亚洲精品福利在线观看| 亚洲国产小视频精品久久久三级| 最近中文字幕高清免费中文字幕mv| 亚洲日韩在线中文字幕综合 | 亚洲美女视频一区| 免费人成视网站在线观看不卡| 日日麻批免费40分钟无码| 国产综合激情在线亚洲第一页| 亚洲视频免费在线观看| 亚洲av片一区二区三区| 一色屋成人免费精品网站| 99在线热播精品免费99热| 亚洲av无码片vr一区二区三区| 中文字幕亚洲综合精品一区| 亚洲精品国产V片在线观看| 久久久久国色AV免费看图片 | 成人免费一级毛片在线播放视频| 一区二区三区免费视频网站 | 国内精自视频品线六区免费 | 免费精品人在线二线三线区别| 国产麻豆一精品一AV一免费| 特级毛片免费观看视频| 在线观看亚洲AV日韩A∨| 777亚洲精品乱码久久久久久 | 五月天婷婷免费视频| 亚洲av无码片vr一区二区三区|