Lucene在结果中查询的机制及在我们项目中的应用
当一次检索完毕后,希望能从上一次检索的结果集合中进行二次查询,以一步步缩小搜索结果结合,比便能够更好地对信息进行筛选。
这种筛选过程,其行为与Filter所要完成的工作非常类似,都是过滤掉一部分文档,只留下另一部分文档。因此,Lucene提供了内置的QueryFilter来帮助完成这种功能。
我们来看一下QueryFilter的源代码:
public class QueryFilter extends CachingWrapperFilter {
/** Constructs a filter which only matches documents matching
* <code>query</code>.
*/
public QueryFilter(Query query) {
super(new QueryWrapperFilter(query));
}
public boolean equals(Object o) {
return super.equals((QueryFilter)o);
}
public int hashCode() {
return super.hashCode() ^ 0x923F64B9;
}
}
可以发现QueryFilter继承了CachingWrapperFilter,而CachingWrapperFilter又继承了Filter。
再看下QueryFilter的构造方法
public QueryFilter(Query query) {
super(new QueryWrapperFilter(query));
}
new了一个QueryWrapperFilter对象,而QueryWrapperFilter继承了Filter,所以QueryFilter本质是个过滤器Filter,对搜索进行二次检索。
下面我们来开下QueryFilter的用法:
//首先构造一个RangeQuery,查找某一时间段内出版的所有文档
Term begin = new Term(“Publishdate”,”1970-01-01”);
Term end = new Term(“publishdate”,”1990-01-01”);
RangeQuery q = new RangeQuery(begin,end,true);
//实例化一个QueryFilter,将RangeQuery赋给它
QueryFilter filter = new QueryFilter(q);
//构造一个TermQuery,查询所有securitylevel为NORMAL的文档
Term normal = new Term(“securitylevel”,SECURITY_NORMAL+””);
TermQuery query = new TermQuery(normal);
//使用上面构造的QueryFilter来进行检索,也就是说,在RangeQuery的基础上,在进行
//TermQuery
IndexSearcher searcher = new IndexSearcher(INDEX_STORE_PATH);
Hits hits = searcher.search(query,filter);
上面的代码就是在第一次RangeQuery查找的结果结合中,进行TermQuery,即在1970-01-01到1990-01-01发行的文档中查找所有安全级别为NORMAL的文档。
因此Lucene在结果中查询的机制就是过滤器查询。
由于我们的项目是从手机客户端向服务器端发送URL查询,所有的信息均在URL中,因此是一种无状态的查询,所以我们每次查询需要汇总URL中的查询信息再进行一次查询。而我们已经实现的过滤器查询其实也就是一种在结果中查询机制的实现,而且我们加入了Lucene的缓存机制,将会使我们的查询速度大大提高。