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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
使用Lucene实现对MySQL数据表的全文检索是一种可行的方案。Lucene是一套开源的全文检索和搜寻的程式库,它提供了一个简单但强大的应用程式接口,能够实现全文索引和搜寻的功能。在Java开发环境中,Lucene是一个成熟的免费开源工具,被广泛应用于信息检索领域。 全文检索是一种针对非结构化数据的检索方法,对于像磁盘上的文件、网站资源等非结构化数据,无法使用SQL语句进行查询,因此需要使用全文检索法。全文检索法将非结构化数据中的一部分信息提取出来进行组织,形成索引,然后根据索引快速定位到要查找的信息。Lucene可以实现全文检索的功能,它是Apache软件基金会支持和提供的工具包。 使用Lucene实现全文检索的流程如下: 1. 创建索引:首先获取要进行检索的文档,可以是磁盘文件或网站资源等,然后构建文档对象,包括多个域,如文件名称、文件路径、文件大小、文件内容等。接下来对文档进行分词,将分词结果创建为索引并添加到索引库中。 2. 索引搜索:创建查询对象,执行查询并渲染结果。在倒排索引词典表中查找对应搜索词的索引,然后找到索引所链接的文档。例如,搜索语法为"fileName:lucene"表示搜索文件名中包含Lucene的文档。 要使用Lucene实现全文检索,首先需要下载和配置Lucene。你可以从官方网站或其他可信的资源下载Lucene的安装包,并按照相应的指南进行配置。然后,你可以使用Lucene提供的API来实现全文检索功能,根据具体需求进行代码编写和调用。 总之,Lucene是一种强大的全文检索工具,可以帮助你在MySQL数据表中实现全文检索功能。你可以通过学习和使用Lucene的API来了解更多关于Lucene的功能和用法,并根据具体需求进行相应的实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [【springboot微服务】Lucence实现Mysql全文检索](https://blog.csdn.net/zhangcongyi420/article/details/129940816)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [【Lucene&Solr】Lucene实现全文检索](https://blog.csdn.net/qq_43705275/article/details/107229299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scud

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值