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

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

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

    使用Lucene進行全文檢索(三)---進行搜索

    scud(飛云小俠) http://www.jscud.com 轉載請注明來源/作者

    關鍵字:lucene,html parser,全文檢索,IndexReader,Document,Field,IndexWriter,Term,HTMLPAGE


     無論是建立索引還是分析內容,都是為了用戶的搜索服務.
     
     在Lucene中,如果需要使用搜索,需要使用Searcher類,這是一個抽象類,它有2個子類:IndexSearcher和MultiSearcher.
     
     IndexSearcher是對一個索引進行搜索,如果你需要對多個索引進行搜索,可以使用MultiSearcher.下面的內容只介紹了IndexSearcher.
     
     搜索涉及到幾個問題:分頁,組合條件,根據條件過濾,排序等等.
     
     分頁:分頁在記錄列表的地方都會遇到,這里不在贅述,我也實現過一個保存分頁結果和顯示結果的類,用于自己的實際工作,下面也會用到保存分頁結果的類,代碼如下:

      package com.jscud.support;
      
      
      /**
       * 分頁顯示用的參數.
       *
       * @author scud(飛云小俠) http://www.jscud.com
       * 
       */
      
      public class DivPageInfo
      {
      
          //開始記錄數
          private int recStart;
      
          //結束記錄數
          private int recEnd;
      
          //總頁數
          private int pageCount;
      
          //當前頁
          private int page;
      
          //記錄總數
          private int recCount;
         
          //每頁記錄數
          private int perPageRows;
      
          public int getNicePageCount()
          {
              return getNicePageNum(pageCount);
          }
         
          //get,set等,不在列出
          //......
      
         
          /**
           * 得到友好的頁數數字,頁數為0時,返回1.
           *
           * @return 得到友好的頁數
           */
          public static int getNicePageNum(int nPage)
          {
                  if (nPage == 0)
                  {
                          return 1;
                  }
                  else
                  {
                          return nPage;
                  }
          }   
      } 

     顯示分頁結果的類就需要大家根據自己使用的框架來具體實現了.我使用的是WebWork.
     
     組合條件:在Lucene中,搜索的條件可以組合的很復雜,相關的類有BooleanQuery, FilteredQuery, MultiTermQuery, PhrasePrefixQuery, PhraseQuery, PrefixQuery, RangeQuery, SpanQuery, TermQuery 等等,從而可以組合出很復雜的條件用于查詢.
     另外QueryParser可以根據用戶輸入的字符串和設定的解析器和字段設置等,可以自動產生新的組合條件用于查詢,例如用戶輸入"john AND black",QueryParser可以自己分析出用戶是需要查詢字段中同時包含"john"和"black"的結果.
     
     過濾條件:有時候根據具體的用戶需求,有些記錄對于一些用戶是不可見的,此時就要使用過濾器來防止不合法的用戶看到不應該看到的記錄.過濾器同時也可以根據一些具體的條件來過濾掉一些用戶不想看到的記錄.如果需要實現自己的filter,只要參考QueryFilter,DateFilter實現Filter即可.
     
     排序:有時候,可能需要根據某個字段進行排序,例如按照時間排序.當然更多的時候是按照搜索結果的符合度進行排序,lucene默認的排序就是按照符合度來進行排序的.
     
     進行搜索的代碼如下,根據自己的需要進行代碼的修改:
     

     /**
     * 進行搜索.
     *
     * 參數依次為:搜索內容(支持lucene語法),當前頁,每頁記錄數,分頁信息對象
     *
     */
        public static List search(String searchText, int page, int perpage, final DivPageInfo pageinfo)
        {
            List docs = new ArrayList();
           
            if(!LuceneSearch.indexExist(indexDir)) { return docs; }

            Searcher searcher = null;
            try
            {
                StandardAnalyzer analyzer = new StandardAnalyzer();

                //處理檢索條件
                Query titleQuery = QueryParser.parse(searchText, "title", analyzer);
                Query contextQuery = QueryParser.parse(searchText, "content", analyzer);
                Query otherQuery = QueryParser.parse(searchText, "other", analyzer);

                BooleanQuery query = new BooleanQuery();
                query.add(titleQuery, false, false);
                query.add(contextQuery, false, false);
                query.add(otherQuery, false, false);

                //分頁檢索
                searcher = new IndexSearcher(indexDir);
                Hits hits = searcher.search(query);

                DivPageInfo.divPage(hits.length(), perpage, page, pageinfo);

                //取出當前頁的記錄
                for (int i = pageinfo.getRecStart(); i <= pageinfo.getRecEnd(); i++)
                {
                    docs.add(LuceneDocument.getDocument(hits.doc(i - 1)));
                }
            }
            catch (IOException e)
            {
                LogMan.error("Error occur When Search Lucene", e);
            }
            catch (ParseException e)
            {
                LogMan.error("Error occur When Search Lucene", e);
            }
            finally
            {
                try
                {
                    if (null != searcher)
                    {
                        searcher.close();
                    }
                }
                catch (IOException e)
                {
                    LogMan.warn("Close searcher Error");
                }
            }

            return docs;
        }



     
     代碼中出現了一個新的類Hits,Hits是lucene的搜索結果集,是lazy load的結果集,只有你真正訪問它,它才去裝載真正的數據.
     
     代碼中還出現了一個LuceneDocument,這是為了在頁面中顯示而寫的一個輔助類,因為lucene的Document是final的,無法進行擴展,而要顯示時間字段必須要調用DateField中的函數,這樣在頁面中顯示就不太直觀了,所以寫了這個輔助類,代碼如下:
     

      package com.jscud.www.support.search;
      
      import java.sql.Timestamp;
      import java.util.Date;
      
      import org.apache.lucene.document.DateField;
      import org.apache.lucene.document.Document;
      import org.apache.lucene.document.Field;
      
      /**
       * 對Lucene的Document的封裝,用于顯示目的.
       *
       * @author scud(飛云小俠) http://www.jscud.com
       *
       */
      public class LuceneDocument
      {
          private Document doc;
         
          public LuceneDocument(Document doc)
          {
              this.doc = doc;
          }
         
          public static LuceneDocument getDocument(Document doc)
          {
              return new LuceneDocument(doc);
          }
         
          public String getValue(String name)
          {
              return doc.get(name);
          }
         
          public Field getField(String name)
          {
              return doc.getField(name);
          }
         
          public Timestamp getDateTime(String name)
          {
              String value = doc.get(name);
              return new Timestamp( DateField.stringToTime(value));
          }
         
          public Date getDate(String name)
          {
              String value = doc.get(name);
              return  DateField.stringToDate(value);       
          }    
      }


     
     使用WebWork對結果集進行了顯示,代碼如下:

              <ww:iterator value="docs">
              <tr >         
              <td>
              <a href="<jscud:contextpath /><ww:property  value="getValue('visiturl')" />"  target="_blank" >
              <ww:property value="getValue('title')" escape="true" />
              </a> &nbsp; (<jscud:datetime value="getDateTime('addtime')" />)
              </td>
              </tr>
              </ww:iterator> 
      



     然后調用分頁信息顯示tag即可.
     
     
     通過以上的應用,可以看到,其實使用lucene很簡單,以前總覺得很神秘,所以一直沒有使用過,用過之后才覺得如此簡單.
     
     
     當然,對于大容量數據下,群集情況下,在網上都有很多解決方案,在此不一一提出,感興趣的讀者可以自己去搜索. :)
     

    posted on 2005-08-12 17:34 Scud(飛云小俠) 閱讀(739) 評論(0)  編輯  收藏 所屬分類: Java

    <2005年8月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    導航

    統計

    公告

    文章發布許可
    創造共用協議:署名,非商業,保持一致

    我的郵件
    cnscud # gmail


    常用鏈接

    留言簿(15)

    隨筆分類(113)

    隨筆檔案(103)

    相冊

    友情鏈接

    技術網站

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲桃色AV无码| 在线看片免费人成视频播| 亚洲国产成人精品久久| 亚洲男人天堂2018av| 特级av毛片免费观看| 成人电影在线免费观看| 亚洲一区二区三区自拍公司| 新最免费影视大全在线播放| 3d成人免费动漫在线观看| 一级女人18毛片免费| 国产性生交xxxxx免费| 亚洲精品乱码久久久久久| 亚洲国产视频一区| 国产三级在线免费观看| 99久久国产热无码精品免费| 国产亚洲一区区二区在线| 国产AV旡码专区亚洲AV苍井空| 99爱在线精品免费观看| 久久久久高潮毛片免费全部播放| 在线观看av永久免费| 西西人体44rt高清亚洲| 香港经典a毛片免费观看看| 亚洲午夜日韩高清一区| 亚洲成AV人片高潮喷水| 日韩在线播放全免费| 国产国拍亚洲精品mv在线观看| 色九月亚洲综合网| 日韩av无码成人无码免费| 亚洲Av熟妇高潮30p| 青青在线久青草免费观看| 亚洲AV无码成人精品区日韩| 国产日本一线在线观看免费| 国产精品亚洲天堂| 宅男666在线永久免费观看 | 国产成人精品免费视频网页大全| 国产成人精品日本亚洲11| 午夜网站在线观看免费完整高清观看 | 亚洲女人18毛片水真多| 福利免费观看午夜体检区 | 特级无码毛片免费视频| 久久久无码精品亚洲日韩京东传媒 |