Lucene4.3开发之第六步之走神中期(六)ITeye - 乐橙lc8

Lucene4.3开发之第六步之走神中期(六)ITeye

2019年02月26日15时19分04秒 | 作者: 鸿志 | 标签: 成果,日子,编程 | 浏览: 2485



转载请注明,原创地址,谢谢合作!
http://qindongliang1922.iteye.com/blog/1934607


散仙前些日子写了两篇Lucene的插曲,分别是关于分词和分页的常识,尽管当成插曲写,可是其内容仍是比较重要的,由于那些常识在实践的运用以及开发顶用的仍是比较常见,所以仍是要用心的了解一下。

散仙今日要写的是关于过滤方面的常识,也就是Filter,假如了解Solr的朋友们,必定都会知道Solr里边fq这个参数,这个参数的效果其实就是lucene里边的过滤,对一些q参数查询的成果集,做过滤或许束缚回来一些咱们需求的内容,能够了解成缩小查找空间的一种战略。

在这里散仙先介绍下查询与过滤的差异和联络,其实查询(各种Query)和过滤(各种Filter)之间十分类似,能够这样说只要用Query能完结的事,用过滤也都能够完结,它们之间能够彼此转化,最大的差异就是运用过滤回来的成果集不带评分操作,而运用Query回来的成果都是带相关性评分的,所以当咱们假如有一些跟评分操作没有联系的事务,优先运用Filter操作,将会获取更好的功用,其实这也是Solr里边的q参数跟fq参数的差异。


下面,开端进入正题,在这之前,散仙仍是喜爱陈词滥调的先来了解一下Lucene里边有关于Filter的全体常识



下面,咱们来看下详细的在代码里怎样完成,先来看下咱们的测试数据
id score bookname ename type price date
1 1 飘渺之旅 pmzl 小说 52.23 201005 
2 1 三国演义 sgyy 小说 36.13 201207 
3 1 数据库实战 sjksz 技能 77.13 200811 
4 1 编程宝典 bcbd 技能 100.3 200501 
5 1 职场联系论 zcgxl 职场 36.59 200501 
6 1 健康日子 jksh 日子 20.47 200008 
7 1 看清实质 kqbz 社会 10.37 201004 
8 1 编程,编程 bcbc 社会 10.37 201004 

中心代码
//运用过滤器 最终一个为true时包含鸿沟部分,为false时不包含鸿沟部分
 //倒数第二个为true时,包含查询鸿沟,为false时不包含
 TermRangeFilter filter=new TermRangeFilter("ename", new BytesRef("h"), new BytesRef("n"), true, true);
 TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默许无排序方法

输出成果
6 1 健康日子 jksh 日子 20.47 200008 
7 1 看清实质 kqbz 社会 10.37 201004 

中心代码
 NumericRangeFilter Double filter=NumericRangeFilter.newDoubleRange("price", 10D, 40D, true, false);
 TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默许无排序方法

输出成果
2 1 三国演义 sgyy 小说 36.13 201207 
5 1 职场联系论 zcgxl 职场 36.59 200501 
6 1 健康日子 jksh 日子 20.47 200008 
7 1 看清实质 kqbz 社会 10.37 201004 
8 1 编程,编程 bcbc 社会 10.37 201004


中心代码
 //运用缓存过滤
 Filter filter=FieldCacheRangeFilter.newDoubleRange("price", 20D, 50D, true, true);
 TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默许无排序方法

输出成果
2 1 三国演义 sgyy 小说 36.13 201207 
5 1 职场联系论 zcgxl 职场 36.59 200501 
6 1 健康日子 jksh 日子 20.47 200008 

中心代码
 // 缓存域过滤特定的类别
 Filter filter=new FieldCacheTermsFilter("type", new String[]{"技能","社会"});
 TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默许无排序方法

输出成果
3 1 数据库实战 sjksz 技能 77.13 200811 
4 1 编程宝典 bcbd 技能 100.3 200501 
7 1 看清实质 kqbz 社会 10.37 201004 
8 1 编程,编程 bcbc 社会 10.37 201004 

中心代码
 //运用QueryWrapperFilter类包装一个Query
 QueryWrapperFilter filter=new QueryWrapperFilter(new TermQuery(new Term("type", "技能")));
 TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默许无排序方法

输出成果
3 1 数据库实战 sjksz 技能 77.13 200811 
4 1 编程宝典 bcbd 技能 100.3 200501 


最终我来看下,怎么承继Filter基类,来定制咱们自己的filter,自定义的Filter,尽管某些时分,功用很强壮灵敏,可是有几个缺陷,咱们的了解1,确保是内容不重复的字段,例如主键,假如重复,默许回来第一个作为成果集显现2,确保不能被分词的内容,假如是分词的字段,则可能会呈现一些不正确的成果。
自定义Filter类
package com.sanjiesanxian.test;
import java.io.IOException;
import java.util.BitSet;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.Filter;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.DocIdBitSet;
import org.apache.lucene.util.FixedBitSet;
import org.apache.lucene.util.OpenBitSet;
 *^_^ ^_^ ^_^
 * QQ沟通讨论群:324714439
 * 自定义过滤器
 * @author 三劫散仙
 * */
public class MyCustomFilter extends Filter{
 public MyCustomFilter() {
 // TODO Auto-generated constructor stub
 private String[] terms;//束缚回来的数据字典
 public MyCustomFilter(String ...terms) {
 // TODO Auto-generated constructor stub
 this.terms=terms;
 @Override
 public DocIdSet getDocIdSet(AtomicReaderContext arg0, Bits arg1)
 throws IOException {
 FixedBitSet bits=new FixedBitSet(arg0.reader().maxDoc()) ;//获取没有一切的docid包含未删去的
 int base=arg0.docBase;//段的相对基数,确保多个段时相对方位正确
 //int limit=base+arg0.reader().maxDoc();//核算最大束缚值
 for(String s:terms){
 DocsEnum doc=arg0.reader().termDocsEnum(new Term("id", s));//有必要是仅有的不重复
 //确保是单个不重复的term,假如重复的话,默许会取第一个作为回来成果集,分词后的term也不适用自定义term
 if(doc.nextDoc()!=-1){ 
 bits.set(doc.docID());//抵挡契合条件束缚的docid循环添加到bits里边
 return bits;                          
			
版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表乐橙lc8立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章