Lucene的搜索功能

来源:互联网 发布:三级分销分成算法 编辑:程序博客网 时间:2024/04/29 04:34

 

【Query】

Query对象有诸多子类:TermQuery、TermRangeQuery、NumericQuery、PrifixQuery前缀查询、WildcardQuery通配符查询、BooleanQuery、PhraseQuery短语查询、FuzzyQuery模糊查询。在搜索时,可以直接创建这些类的对象,也可以使用QueryParser将查询字符串解析为某种查询对象。

 

【QueryParser】

QueryParser可以理解为生产Query对象的工厂,原料是查询字符串,产品是相应的查询对象。我们还可以继承QueryParser,覆盖其中性能较低的通配符查询和模糊查询(在获取这两个查询对象时抛异常);同时可以扩展对数字和日期范围的检索(覆盖其getRangeQuery方法,在方法体中判断域值如果为数字的话,强制转为数字,调用NumberRangeQuery.newIntRange方法返回查询对象)。

 

 

文档Id存储在索引文件中,应该是在建立索引文件的时候分配的。

【ScoreDoc】

在进行搜索时,我们需要的结果是一个按照一定顺序(默认按照文档得分由高到低)排列的文档Id的序列,这样我们就能调用searcher.doc(docId)依次展现匹配到的文档信息了。Lucene中的ScoreDoc对象包含有文档Id和文档得分的属性(分别为doc和score属性),如果搜索返回的结果是一个按照得分排列的ScoreDoc对象数组即可。这样就可以通过sd.doc依次获得文档Id了。

【TopDocs】

这样返回按说也没有问题的,但是会缺少一个信息——匹配查询条件的文档总数。所以Lucene又将这个所有匹配文档的总数跟ScoreDoc对象数组封装成了TopDocs对象,并将它作为searcher.search()方法的返回值。

 

分页查询是通过再查询的方式实现的。

两种方式:要么是通过对ScoreDoc对象数组中按照页码和每页记录数抽取片段,要么是通过searcher.searchAfter(lastScoreDoc,query,pageSize)这个方法实现的。不过后者需要先查询出上一页最后一个ScoreDoc对象。

 

搜索排序的对searcher.search方法的Sort参数做文章的。可以根据分值排序,根据索引号排序,根据不同的域排序。

 

搜索过滤的对searcher.search方法的Filter参数做文章的。有TermRangeQuery、NumericRangeQuery、QueryWrapperFilter,另外还可以自定义过滤器(覆盖Filter类中的getDocIdSet方法),在索引文件不变的情况下过滤临时数据。

 

自定义评分的对searcher.search方法的Query参数做文章的。Lucene中有个Query的子类CustomScoreQuery,可以继承该类,覆盖其getCustomScoreProvider方法。这就该需要再构建一个类,继承CustomScoreProvider类,覆盖其customScore方法。如果想基于某个域的值设计评分算法,那就需要通过域缓存获取该域的值。

String[] filenames = FieldCache.DEFAULT.getStrings(reader, "filename");

 

 

 

 

 

原创粉丝点击