<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 轉(zhuǎn)載請注明來源/作者

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


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

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

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

     /**
     * 進行搜索.
     *
     * 參數(shù)依次為:搜索內(nèi)容(支持lucene語法),當前頁,每頁記錄數(shù),分頁信息對象
     *
     */
        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;
        }



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

      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> 
      



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

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

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

    導航

    統(tǒng)計

    公告

    文章發(fā)布許可
    創(chuàng)造共用協(xié)議:署名,非商業(yè),保持一致

    我的郵件
    cnscud # gmail


    常用鏈接

    留言簿(15)

    隨筆分類(113)

    隨筆檔案(103)

    相冊

    友情鏈接

    技術網(wǎng)站

    搜索

    積分與排名

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 黄色a级片免费看| 永久看日本大片免费35分钟| 亚洲av无码一区二区三区网站| 高清一区二区三区免费视频| 亚洲精品123区在线观看| 亚洲人成色7777在线观看不卡| 日本免费久久久久久久网站| 亚洲私人无码综合久久网| 亚洲色偷偷狠狠综合网| 免费观看国产网址你懂的| 免费看一级一级人妻片 | 亚洲视频小说图片| 国产成人免费片在线视频观看| 青青青国产手机频在线免费观看 | 亚洲精品老司机在线观看| 3344永久在线观看视频免费首页| 亚洲国产AV无码一区二区三区 | 免费无码一区二区| 亚洲激情校园春色| 中文字幕亚洲图片| 免费高清av一区二区三区| 免费在线观看一级片| 黄网站色成年片大免费高清| 亚洲成av人片在线看片| 中文字幕亚洲图片| 免费一级毛片不卡不收费| 四虎精品视频在线永久免费观看| h片在线观看免费| 亚洲av无码专区在线观看下载| 日韩亚洲Av人人夜夜澡人人爽| 亚洲女同成人AⅤ人片在线观看| 91成人免费观看网站| 美女视频黄a视频全免费网站色窝| 色天使亚洲综合一区二区| 亚洲色图激情文学| 亚洲欧洲一区二区| 国产亚洲成av人片在线观看| 亚洲精品国产精品乱码不卞| 处破痛哭A√18成年片免费| 一本岛高清v不卡免费一三区| 久久综合国产乱子伦精品免费|