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);//默认无排序方式
输出结果
//使用QueryWrapperFilter类包装一个Query
QueryWrapperFilter filter=new QueryWrapperFilter(new TermQuery(new Term("type", "技术")));
TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);//默认无排序方式
最后我来看下,如何继承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;
}
}
测试查询代码
MyCustomFilter filter=new MyCustomFilter("3","5","2");//随意指定1之多个需要过滤的项
TopDocs topDocs=searcher.search(new MatchAllDocsQuery(),filter,10000);
输出结果
2 1 三国演义 sgyy 小说 36.13 201207
3 1 数据库实战 sjksz 技术 77.13 200811
5 1 职场关系论 zcgxl 职场 36.59 200501
自定义过滤器虽然有缺点,但是某些场景下却能发挥很灵活的作用,特别是对没有分词的字段进行过滤操作。
lucene 过滤结果的更多相关文章
- 1.7.4 Query Syntax and Parsing
1. 查询语法和解析 这部分主要说明了如何指定被使用的查询解析器.同样描述了主查询解析器的支持的语法和功能.同时还描述了在特定环境下使用的其他查询解析器.这里有一些普通查询解析器都能使用的参数,将会在 ...
- 【lucene系列学习四】使用IKAnalyzer分词器实现敏感词和停用词过滤
Lucene自带的中文分词器SmartChineseAnalyzer不太好扩展,于是我用了IKAnalyzer来进行敏感词和停用词的过滤. 首先,下载IKAnalyzer,我下载了 然后,由于IKAn ...
- lucene整理3 -- 排序、过滤、分词器
1. 排序 1.1. Sort类 public Sort() public Sort(String field) public Sort(String field,Boolean reverse ...
- lucene 范围过滤
Lucene里面有关于Filter的整体知识 下面,我们来看下具体的在代码里怎么实现,先来看下我们的测试数据 Java代码 id score bookname ena ...
- lucene查询索引库、分页、过滤、排序、高亮
2.查询索引库 插入测试数据 xx.xx. index. ArticleIndex @Test public void testCreateIndexBatch() throws Exception{ ...
- lucene自定义过滤器
先介绍下查询与过滤的区别和联系,其实查询(各种Query)和过滤(各种Filter)之间非常相似,可以这样说只要用Query能完成的事,用过滤也都可以完成,它们之间可以相互转换,最大的区别就是使用过滤 ...
- MySQL和Lucene索引对比分析
MySQL和Lucene都可以对数据构建索引并通过索引查询数据,一个是关系型数据库,一个是构建搜索引擎(Solr.ElasticSearch)的核心类库.两者的索引(index)有什么区别呢?以前写过 ...
- Lucene系列-FieldCache
域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值. 用途及使用场景 当用户需要访问各文档中某个域的值时,IndexSearcher.doc(docId)获得Document的所有域值,但 ...
- Apache Lucene(全文检索引擎)—分词器
目录 返回目录:http://www.cnblogs.com/hanyinglong/p/5464604.html 本项目Demo已上传GitHub,欢迎大家fork下载学习:https://gith ...
随机推荐
- SurfaceHolder.Callback
Class Overview A client may implement this interface to receive information about changes to the sur ...
- a链接onclick="window.location.href=在ie6上面无法执行解决
<a href="javascript:void(0)" onclick="window.location.href=document.getElementById ...
- Webservice接口和Http接口
WebService又是一种高级应用,与之前学习的Struts.Spring.Hibernate等框架不同.WebService是面向服务的架构(SOA),看起来像是比SSH框架要大.那么它到底是做什 ...
- 20160808_安装JDK7u79
1.将 jdk-7u79-linux-x64.tar.gz 解压,得到文件夹“jdk1.7.0_79” 将 文件夹“jdk1.7.0_79” 复制到 “/usr/java/”下 2.配置环境变量: 文 ...
- easyui-datebox 和easyui-datetimebox 设置默认时间当前时间
//显示当前日期 formatterDate = function (date) { var day = date.getDate() > 9 ? date.getDate() : " ...
- OpenCV3编程入门笔记(6)自我验证各函数程序代码
// asw.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <opencv2/opencv.hpp> usi ...
- iOS 沙盒(sandbox)机制和文件操作
本文参看了 http://www.uml.org.cn/mobiledev/201209211.asp#1 这篇文章中的介绍,尊重原著. 1.IOS沙盒机制 IOS应用程序只能在本应用程序中创建的文件 ...
- MySQL redo lock 死锁问题排查 & 解决过程
版权声明:本文由张青林原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/181 来源:腾云阁 https://www.qclo ...
- Unity5.3官方VR教程重磅登场-系列2
作者:王寒链接:https://zhuanlan.zhihu.com/p/20485529来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 欢迎继续我们的学习. 北京时间 ...
- 高可用性中的脑裂问题(split-brain problem in HA)(转)
欢迎关注我的社交账号: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://gith ...