乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      學習 Lucene 原來可以那么簡單!

       沙門空海 2018-03-21


      博客鏈接:https://my.oschina.net/u/3777556/blog/1647031

      作者:Java3y


      什么是Lucene??



      Lucene 是 apache 軟件基金會發(fā)布的一個開放源代碼的全文檢索引擎工具包,由資深全文檢索專家 Doug Cutting 所撰寫,它是一個全文檢索引擎的架構,提供了完整的創(chuàng)建索引和查詢索引,以及部分文本分析的引擎。


      Lucene的目的是為軟件開發(fā)人員提供一個簡單易用的工具包,以方便在目標系統(tǒng)中實現(xiàn)全文檢索的功能,或者是以此為基礎建立起完整的全文檢索引擎,Lucene在全文檢索領域是一個經(jīng)典的祖先,現(xiàn)在很多檢索引擎都是在其基礎上創(chuàng)建的,思想是相通的。


      Lucene是根據(jù)關健字來搜索的文本搜索工具,只能在某個網(wǎng)站內部搜索文本內容,不能跨網(wǎng)站搜索。


      既然談到了網(wǎng)站內部的搜索,那么我們就談談我們熟悉的百度、google那些搜索引擎又是基于什么搜索的呢....

       

       

       

       

      從圖上已經(jīng)看得很清楚,baidu、google等搜索引擎其實是通過網(wǎng)絡爬蟲的程序來進行搜索的...


      為什么我們要用Lucene?



      在介紹Lucene的時候,我們已經(jīng)說了:Lucene又不是搜索引擎,僅僅是在網(wǎng)站內部進行文本的搜索。那我們?yōu)槭裁匆獙W他呢???


      我們之前編寫納稅服務系統(tǒng)的時候,其實就已經(jīng)使用過SQL來進行站內的搜索..


      既然SQL能做的功能,我們還要學Lucene,為什么呢???


      我們來看看我們用SQL來搜索的話,有什么缺點:


      • (1)SQL只能針對數(shù)據(jù)庫表搜索,不能直接針對硬盤上的文本搜索

      • (2)SQL沒有相關度排名

      • (3)SQL搜索結果沒有關健字高亮顯示

      • (4)SQL需要數(shù)據(jù)庫的支持,數(shù)據(jù)庫本身需要內存開銷較大,例如:Oracle

      • (5)SQL搜索有時較慢,尤其是數(shù)據(jù)庫不在本地時,超慢,例如:Oracle

       

       

      我們來看看在baidu中搜索Lucene為關鍵字搜索出的內容是怎么樣的:

       

       

      以上所說的,我們如果使用SQL的話,是做不到的。因此我們就學習Lucene來幫我們在站內根據(jù)文本關鍵字來進行搜索數(shù)據(jù)!


      我們如果網(wǎng)站需要根據(jù)關鍵字來進行搜索,可以使用SQL,也可以使用Lucene...那么我們Lucene和SQL是一樣的,都是在持久層中編寫代碼的。。

       

       

      一、快速入門



      接下來,我們就講解怎么使用Lucene了.....在講解Lucene的API之前,我們首先來講講Lucene存放的究竟是什么內容...我們的SQL使用的是數(shù)據(jù)庫中的內存,在硬盤中為DBF文件...那么我們Lucene內部又是什么東西呢??


      Lucene中存的就是一系列的二進制壓縮文件和一些控制文件,它們位于計算機的硬盤上, 這些內容統(tǒng)稱為索引庫,索引庫有二部份組成:


      • (1)原始記錄

        • 存入到索引庫中的原始文本,例如:我是鐘福成

      • (2)詞匯表

        • 按照一定的拆分策略(即分詞器)將原始記錄中的每個字符拆開后,存入一個供將來搜索的表


      也就是說:Lucene存放數(shù)據(jù)的地方我們通常稱之為索引庫,索引庫又分為兩部分組成:原始記錄和詞匯表....


      1.1原始記錄和詞匯表


      當我們想要把數(shù)據(jù)存到索引庫的時候,我們首先存入的是將數(shù)據(jù)存到原始記錄上面去....


      又由于我們給用戶使用的時候,用戶使用的是關鍵字來進行查詢我們的具體記錄。因此,我們需要把我們原始存進的數(shù)據(jù)進行拆分!將拆分出來的數(shù)據(jù)存進詞匯表中。


      詞匯表就是類似于我們在學Oracle中的索引表,拆分的時候會給出對應的索引值。


      一旦用戶根據(jù)關鍵字來進行搜索,那么程序就先去查詢詞匯表中有沒有該關鍵字,如果有該關鍵字就定位到原始記錄表中,將符合條件的原始記錄返回給用戶查看。


      我們查看以下的圖方便理解:

       

       

      到了這里,有人可能就會疑問:難道原始記錄拆分的數(shù)據(jù)都是一個一個漢字進行拆分的嗎??然后在詞匯表中不就有很多的關鍵字了???


      其實,我們在存到原始記錄表中的時候,可以指定我們使用哪種算法來將數(shù)據(jù)拆分,存到詞匯表中.....我們的圖是Lucene的標準分詞算法,一個一個漢字進行拆分。我們可以使用別的分詞算法,兩個兩個拆分或者其他的算法。


      1.2編寫第一個Lucene程序


      首先,我們來導入Lucene的必要開發(fā)包:


      • lucene-core-3.0.2.jar【Lucene核心】

      • lucene-analyzers-3.0.2.jar【分詞器】

      • lucene-highlighter-3.0.2.jar【Lucene會將搜索出來的字,高亮顯示,提示用戶】

      • lucene-memory-3.0.2.jar【索引庫優(yōu)化策略】


      創(chuàng)建User對象,User對象封裝了數(shù)據(jù)....



      /**

       * Created by ozc on 2017/7/12.

       */

      public class User {



          private String id ;

          private String userName;

          private String sal;


          public User() {


          }

          public User(String id, String userName, String sal) {

              this.id = id;

              this.userName = userName;

              this.sal = sal;

          }

          public String getId() {

              return id;

          }


          public void setId(String id) {

              this.id = id;

          }


          public String getUserName() {

              return userName;

          }


          public void setUserName(String userName) {

              this.userName = userName;

          }


          public String getSal() {

              return sal;

          }


          public void setSal(String sal) {

              this.sal = sal;

          }

      }


      我們想要使用Lucene來查詢出站內的數(shù)據(jù),首先我們得要有個索引庫吧!于是我們先創(chuàng)建索引庫,將我們的數(shù)據(jù)存到索引庫中。


      創(chuàng)建索引庫的步驟:


      • 1)創(chuàng)建JavaBean對象

      • 2)創(chuàng)建Docment對象

      • 3)將JavaBean對象所有的屬性值,均放到Document對象中去,屬性名可以和JavaBean相同或不同

      • 4)創(chuàng)建IndexWriter對象

      • 5)將Document對象通過IndexWriter對象寫入索引庫中

      • 6)關閉IndexWriter對象




      程序執(zhí)行完,我們就會在硬盤中見到我們的索引庫。

       

       

      那我們現(xiàn)在是不知道記錄是否真真正正存儲到索引庫中的,因為我們看不見。索引庫存放的數(shù)據(jù)放在cfs文件下,我們也是不能打開cfs文件的。


      于是,我們現(xiàn)在用一個關鍵字,把索引庫的數(shù)據(jù)讀取。看看讀取數(shù)據(jù)是否成功。


      根據(jù)關鍵字查詢索引庫中的內容:


      • 1)創(chuàng)建IndexSearcher對象

      • 2)創(chuàng)建QueryParser對象

      • 3)創(chuàng)建Query對象來封裝關鍵字

      • 4)用IndexSearcher對象去索引庫中查詢符合條件的前100條記錄,不足100條記錄的以實際為準

      • 5)獲取符合條件的編號

      • 6)用indexSearcher對象去索引庫中查詢編號對應的Document對象

      • 7)將Document對象中的所有屬性取出,再封裝回JavaBean對象中去,并加入到集合中保存,以備將之用



      效果:

       


      1.3進一步說明Lucene代碼


      我們的Lucene程序就是大概這么一個思路:將JavaBean對象封裝到Document對象中,然后通過IndexWriter把document寫入到索引庫中。當用戶需要查詢的時候,就使用IndexSearcher從索引庫中讀取數(shù)據(jù),找到對應的Document對象,從而解析里邊的內容,再封裝到JavaBean對象中讓我們使用。

       

       

      二、對Lucene代碼優(yōu)化



      我們再次看回我們上一篇快速入門寫過的代碼,我來截取一些有代表性的:


      以下代碼在把數(shù)據(jù)填充到索引庫,和從索引庫查詢數(shù)據(jù)的時候,都出現(xiàn)了。是重復代碼!



      以下的代碼其實就是將JavaBean的數(shù)據(jù)封裝到Document對象中,我們是可以通過反射來對其進行封裝....如果不封裝的話,我們如果有很多JavaBean都要添加到Document對象中,就會出現(xiàn)很多類似的代碼。



      以下代碼就是從Document對象中把數(shù)據(jù)取出來,封裝到JavaBean去。如果JavaBean中有很多屬性,也是需要我們寫很多次類似代碼....



      2.1編寫Lucene工具類


      在編寫工具類的時候,值得注意的地方:


      • 當我們得到了對象的屬性的時候,就可以把屬性的get方法封裝起來

      • 得到get方法,就可以調用它,得到對應的值

      • 在操作對象的屬性時,我們要使用暴力訪問

      • 如果有屬性,值,對象這三個變量,我們記得使用BeanUtils組件



      2.2使用LuceneUtils改造程序



      三、索引庫優(yōu)化



      我們已經(jīng)可以創(chuàng)建索引庫并且從索引庫讀取對象的數(shù)據(jù)了。其實索引庫還有地方可以優(yōu)化的....


      3.1合并文件


      我們把數(shù)據(jù)添加到索引庫中的時候,每添加一次,都會幫我們自動創(chuàng)建一個cfs文件...

       

       

      這樣其實不好,因為如果數(shù)據(jù)量一大,我們的硬盤就有非常非常多的cfs文件了.....其實索引庫會幫我們自動合并文件的,默認是10個。


      如果,我們想要修改默認的值,我們可以通過以下的代碼修改:



      3.2設置內存索引庫


      我們的目前的程序是直接與文件進行操作,這樣對IO的開銷其實是比較大的。而且速度相對較慢....我們可以使用內存索引庫來提高我們的讀寫效率...


      對于內存索引庫而言,它的速度是很快的,因為我們直接操作內存...但是呢,我們要將內存索引庫是要到硬盤索引庫中保存起來的。當我們讀取數(shù)據(jù)的時候,先要把硬盤索引庫的數(shù)據(jù)同步到內存索引庫中去的。

       


      四、分詞器



      我們在前面中就已經(jīng)說過了,在把數(shù)據(jù)存到索引庫的時候,我們會使用某些算法,將原始記錄表的數(shù)據(jù)存到詞匯表中.....那么這些算法總和我們可以稱之為分詞器


      分詞器: ** 采用一種算法,將中英文本中的字符拆分開來,形成詞匯,以待用戶輸入關健字后搜索**


      對于為什么要使用分詞器,我們也明確地說過:由于用戶不可能把我們的原始記錄數(shù)據(jù)完完整整地記錄下來,于是他們在搜索的時候,是通過關鍵字進行對原始記錄表的查詢....此時,我們就采用分詞器來最大限度地匹配相關的數(shù)據(jù)

       

       

      4.1分詞器流程


      • 步一:按分詞器拆分出詞匯

      • 步二:去除停用詞和禁用詞

      • 步三:如果有英文,把英文字母轉為小寫,即搜索不分大小寫


      4.2分詞器API


      我們在選擇分詞算法的時候,我們會發(fā)現(xiàn)有非常非常多地分詞器API,我們可以用以下代碼來看看該分詞器是怎么將數(shù)據(jù)分割的:



      在實驗完之后,我們就可以選擇恰當?shù)姆衷~算法了....


      4.3IKAnalyzer 分詞器


      這是一個第三方的分詞器,我們如果要使用的話需要導入對應的jar包


      • IKAnalyzer3.2.0Stable.jar

      • 步二:將IKAnalyzer.cfg.xml和stopword.dic和xxx.dic文件復制到MyEclipse的src目錄下,再進行配置,在配置時,首行需要一個空行


      這個第三方的分詞器有什么好呢????他是中文首選的分詞器...也就是說:他是按照中文的詞語來進行拆分的!

      五、對搜索結果進行處理



      5.1搜索結果高亮


      我們在使用SQL時,搜索出來的數(shù)據(jù)是沒有高亮的...而我們使用Lucene,搜索出來的內容我們可以設置關鍵字為高亮...這樣一來就更加注重用戶體驗了!



      5.2搜索結果摘要


      如果我們搜索出來的文章內容太大了,而我們只想顯示部分的內容,那么我們可以對其進行摘要...


      值得注意的是:搜索結果摘要需要與設置高亮一起使用



      5.3搜索結果排序


      我們搜索引擎肯定用得也不少,使用不同的搜索引擎來搜索相同的內容。他們首頁的排行順序也會不同...這就是它們內部用了搜索結果排序....

      影響網(wǎng)頁的排序有非常多種:


      • head/meta/【keywords關鍵字】

      • 網(wǎng)頁的標簽整潔

      • 網(wǎng)頁執(zhí)行速度

      • 采用div+css

      • 等等等等


      而在Lucene中我們就可以設置相關度得分來使不同的結果對其進行排序:


      IndexWriter indexWriter = new IndexWriter(LuceneUtil.getDirectory(),LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());

      //為結果設置得分

      document.setBoost(20F);

      indexWriter.addDocument(document);

      indexWriter.close();


      當然了,我們也可以按單個字段排序:



      也可以按多個字段排序:在多字段排序中,只有第一個字段排序結果相同時,第二個字段排序才有作用 提倡用數(shù)值型排序



      5.4條件搜索


      在我們的例子中,我們使用的是根據(jù)一個關鍵字來對某個字段的內容進行搜索。語法類似于下面:



      其實,我們也可以使用關鍵字來對多個字段進行搜索,也就是多條件搜索。我們實際中常常用到的是多條件搜索,多條件搜索可以使用我們最大限度匹配對應的數(shù)據(jù)!


      QueryParser queryParser = new MultiFieldQueryParser(LuceneUtil.getVersion(),new String[]{'content','title'},LuceneUtil.getAnalyzer());


      六、總結



      • Lucene是全文索引引擎的祖先,后面的Solr、Elasticsearch都是基于Lucene的(后面會有一篇講Elasticsearch的,敬請期待~)

      • Lucene中存的就是一系列的二進制壓縮文件和一些控制文件,這些內容統(tǒng)稱為索引庫,索引庫又分了兩個部分:

        • 原始記錄

        • 詞匯表

      • 了解索引庫的優(yōu)化方式:1、合并文件 2、設置內存索引庫

      • Lucene的分詞器有非常多種,選擇自己適合的一種進行分詞

      • 查詢出來的結果可對其設置高亮、摘要、排序


      這篇這是Lucene的冰山一角,一般現(xiàn)在用的可能都是Solr、Elasticsearch的了,但想要更加深入了解Lucene可翻閱其他資料哦~


        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多