使用Lucene进行全文检索(三)---进行搜索(转载)
转载:http://www.jscud.com/srun/news/viewhtml/3_2005_8/78.htm
?
关键字:lucene,html parser,全文检索,indexreader,document,field,indexwriter,term,htmlpage
?无论是建立索引还是分析内容,都是为了用户的搜索服务.
?
?在lucene中,如果需要使用搜索,需要使用searcher类,这是一个抽象类,它有2个子类:indexsearcher和multisearcher.
?
?indexsearcher是对一个索引进行搜索,如果你需要对多个索引进行搜索,可以使用multisearcher.下面的内容只介绍了indexsearcher.
?
?搜索涉及到几个问题:分页,组合条件,根据条件过滤,排序等等.
?
?分页:分页在记录列表的地方都会遇到,这里不在赘述,我也实现过一个保存分页结果和显示结果的类,用于自己的实际工作,下面也会用到保存分页结果的类,代码如下:
?显示分页结果的类就需要大家根据自己使用的框架来具体实现了.我使用的是webwork.
?
?组合条件:在lucene中,搜索的条件可以组合的很复杂,相关的类有booleanquery, filteredquery, multitermquery, phraseprefixquery, phrasequery, prefixquery, rangequery, spanquery, termquery 等等,从而可以组合出很复杂的条件用于查询.
?另外queryparser可以根据用户输入的字符串和设定的解析器和字段设置等,可以自动产生新的组合条件用于查询,例如用户输入"john and black",queryparser可以自己分析出用户是需要查询字段中同时包含"john"和"black"的结果.
?
?过滤条件:有时候根据具体的用户需求,有些记录对于一些用户是不可见的,此时就要使用过滤器来防止不合法的用户看到不应该看到的记录.过滤器同时也可以根据一些具体的条件来过滤掉一些用户不想看到的记录.如果需要实现自己的filter,只要参考queryfilter,datefilter实现filter即可.
?
?排序:有时候,可能需要根据某个字段进行排序,例如按照时间排序.当然更多的时候是按照搜索结果的符合度进行排序,lucene默认的排序就是按照符合度来进行排序的.
?
?进行搜索的代码如下,根据自己的需要进行代码的修改:
?
??????? 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中的函数,这样在页面中显示就不太直观了,所以写了这个辅助类,代码如下:
?
?
?使用webwork对结果集进行了显示,代码如下: