Java资源网

| JAVA基础 | 环境配置 | JDBC | 线程技术 | Socket编程 | JavaMail | JAVA与XML | 设计模式 | 技术新闻 | Java认证 | 程序人生 软件下载
| JSP&Servlet | Spring | Struts | Hibernate | JBuilder | Eclipse | WebService | EJB技术 | J2ME开发 | 应用服务器 | JXTA | Ajax
Articles search文章搜索
   关键字:
   类 别:
       
New download 最新下载
· [组件]HTML Parser 1.5
· [教程]WebSphere Studio应用教程
· [组件]JDom 1.0
· [工具]Junit3.8.1
· [教程]EJB编程及J2EE系统架构和设计
· [教程]EJB教程
· [教程]J2EE Tutorial中文版
· [教程]Java编程思想2(英文)
· [教程]java编程思想(完整版)
· [教程]Java网络编程
New articles 最新文章
· 设计移动 Web 服务
· 解析XML的时候完全忽略DTD
· 理解XML Schema XML Schema 初步
· 标签库的深入研究
· 提升JSP应用程序的七大绝招
· 如何使用JDOM对XML文件进行操作
· 处理XML字符串中特殊字符
· 利用Digester把XML转换成为Java对象
· 使用WebService 和RMI远程协作
· 使用Axis开发Web Service程序
Articles top 热门文章
· Eclipse基础--plugin插件安装(6644)
· eclipse+tomcat+lomboz的安装配置说明(4774)
· Java程序员就业前景(4584)
· Windows下JAVA环境变量的设置祥解(3788)
· Tomcat下JSP、Servlet和JavaBean环境的配置(3716)
· 使用links方式安装Eclipse插件(3698)
· 一个老程序员的心理话(3533)
· linux下jdk的安装与配置(3459)
· 初学者入门:Structs中基本配置入门(3334)
· Eclipse 运行命令行参数大全(3084)
您的位置:首页>>JSP和Servlet>>使用Lucene进行全文检索(三)---进行搜索
使用Lucene进行全文检索(三)---进行搜索
2005-08-17   来源:CSDN  作者:scud

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很简单,以前总觉得很神秘,所以一直没有使用过,用过之后才觉得如此简单.
 
 
 当然,对于大容量数据下,群集情况下,在网上都有很多解决方案,在此不一一提出,感兴趣的读者可以自己去搜索. :)

  --相关文章--
· 漫步j2ee之jsp技术(1) (2007-04-13)
· 提升JSP应用程序的七大绝招 (2007-04-13)
· 如何在JSP中处理中文 (2007-04-13)
· 第一章 taglibnbsp;原理和实现 (2007-04-13)
· 用jsp动态输出excel文档和中文乱码问题的解决 (2007-04-13)
· 可以自动跳转到出错页面的servlet jsp框架 (2007-04-13)

版权所有©2005-2006 JAVA资源网 渝ICP备05007591号 虚拟主机 | 关于我们 | 联系方式 | 广告业务 | 网站地图 | 友情链接