过滤器在生产环境中应用也比较多。比如禁用词的过滤显示、推荐商品的过期设置等。

在编写时,需要在incrementToken添加自己的过滤规则。,下面的demo是针对同义词编写的过滤。过滤器的编写也可以参照org.apache.lucene.analysis.cn.ChineseFilter进行编写。

使用自定义过滤器进行查询

package com.johnny.lucene04.advance_search;

import java.io.IOException;

import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;

public class CustomFilter {
/**
 * 用户自定义Filter,通过Filter进行数据过滤,在这里可以通过ioc注入方式或者配置文件的方式针对多种情况添加不通的过滤器
 */
    public void searchByCustomFilter(){
        try {
            IndexSearcher search = new IndexSearcher(DirectoryReader.open(FileIndexUtils.getDirectory()));
            Query q = new TermQuery(new Term("content","java"));
            TopDocs tds = search.search(q, new MyIDFilter(new FilterAccessor() {

@Override
                public String[] needOperateValues() {
                    /**显示ID
                    String[] ids = new String[]{"1","2","3","4","5"};
                    return ids;
                    **/
                    /**按照fileName进行展示**/
                    String[] fileNames = new String[]{"MySameAnalyzer.txt","MySameAnalyzer副本 13.txt"};
                    return fileNames;
                }

@Override
                public String getField() {
                /**    String field = "id"; **/
                    String field = "fileName";
                    return field;
                }

@Override
                public boolean hasSet() {
                    return true;
                }
                
            }),200);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document d = search.doc(sd.doc);
                System.out.println(sd.doc+":("+sd.score+")" +
                        "["+d.get("fileName")+"【"+d.get("path")+"】--->"+
                        d.get("size")+"------------>"+d.get("id"));
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

package com.johnny.lucene04.advance_search;
/**
 * 定义数据处理的接口,用来提高数据处理的通用性
 * 使用情况参见customFilter和MyIdFilter
 * @author Johnny
 *
 */
public interface FilterAccessor {
    public String[] needOperateValues();//获取需要处理的元素
    
    public String getField();//需要进行过滤的字段(也就是所谓的域)
    /**
     * 如果返回值为true,表示needOperateValues需要进行显示,
     * 如果返回值为false,表示needOperateValues需要进行隐藏
     **/
    public boolean hasSet();//设定需要处理的数据是否通过过滤
}

自定义过滤器

package com.johnny.lucene04.advance_search;

import java.io.IOException;

import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.OpenBitSet;
/**
 * 自定义过滤器,每次查询都会进行过滤,所以最好做成单例,保存在内存中。
 * @author Johnny
 *
 */
public class MyIDFilter extends Filter {
    
    private FilterAccessor filterAccessor;
    
    
    public MyIDFilter(FilterAccessor filterAccessor){
        this.filterAccessor = filterAccessor;
    }
    /**
     * 对于特价商品的Filter,可以反过来处理,将符合条件的设置为1,不符合条件的默认即可(默认为0)
     */
    @Override
    public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs)
            throws IOException {
        //openBitset是docIdSet的实现类,obs默认值都是0,0表示不显示,1表示显示
        //获取所有的docId
        OpenBitSet obs = new OpenBitSet(context.reader().maxDoc());
        //int base = context.docBase;//段的相对基数,保证多个段时相对位置正确
        
        if(filterAccessor.hasSet()){
             set(context, obs);
        }else{
             clear(context, obs);
        }
        
        return obs;
    }
    /**
     * 用来设置docidset值为1,证明通过过滤
     */
    private void set(AtomicReaderContext context,OpenBitSet obs){
        //设置不通过过滤ID的位置的值为0
        for(String id:filterAccessor.needOperateValues()){
            try {
                DocsEnum de = context.reader().termDocsEnum(new Term(filterAccessor.getField(),id));//必须是唯一的不重复  
                 //保证是单个不重复的term,如果重复的话,默认会取第一个作为返回结果集,分词后的term也不适用自定义term
                if(de.nextDoc()!=-1){
                    obs.set(de.docID());//将符合条件的doc的值设置为1,默认为0
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 用来设置docidset值为0,证明不通过过滤
     */
    private void clear(AtomicReaderContext context,OpenBitSet obs){
        try{
            /** //先把元素填满 //set的值为docId,这里设置完成后,就会将值设置为1,表示会通过过滤**/
            obs.set(0,context.reader().maxDoc());
            for(String id:filterAccessor.needOperateValues()){
                DocsEnum de = context.reader().termDocsEnum(new Term(filterAccessor.getField(),id));//必须是唯一的不重复  
                 //保证是单个不重复的term,如果重复的话,默认会取第一个作为返回结果集,分词后的term也不适用自定义term
                if(de.nextDoc()!=-1){
                    obs.clear(de.docID());;//将符合条件的doc的值设置为0,默认为1
                }
            }
        }catch(IOException e){
            e.printStackTrace();
        }
    }

}

测试方法:

@Test
    public void testCustomFilter(){
        CustomFilter cf = new CustomFilter();
        cf.searchByCustomFilter();
    }

Lucene4.10使用教程(六):Lucene的过滤器相关推荐

  1. 以太坊构建DApps系列教程(六):使用定制代币进行投票

    在本系列关于使用以太坊构建DApps教程的第5部分中,我们讨论了如何为Story添加内容,查看如何添加参与者从DAO购买代币的功能以及在Story中添加提交内容.现在是编写DAO最终形式的时候了:投票 ...

  2. WPF教程六:布局之Grid面板(转)

    WPF教程六:布局之Grid面板 Grid:网格面板 Grid顾名思义就是"网格",以表格形式布局元素,对于整个面板上的元素进行布局,它的子控件被放在一个一个事先定义好的小格子里面 ...

  3. 米思齐(Mixly)图形化系列教程(六)-for循环

    目录 For执行过程 省略 省略'循环变量赋值' 省略'循环条件' 省略"循环变量增量" FOR循环使用举例 遍历数组 顺序输出数据 指定程序重复执行次数 死循环 求和 教程导航 ...

  4. sqli-labs 1~10关教程

    sqlli-labs 1~10关教程 本篇有点长,建议使用目录查看自己想看的关卡 第一关 输入?id=1 出现如下图 输入id=1' 出现语法错误 表示这里可能出现sql注入漏洞 进一步尝试 输入 i ...

  5. ES学习记录10.2——ES分析器3(标记过滤器)

     作为分析器三大组成部分的另一部分,标记过滤器(token filters)是非必要的.token filters从标记生成器tokenizer那里接受标记输入流,可以用来修改(如将术语转成小写).删 ...

  6. lucene4.10.3入门

    最近在研究搜索殷勤的全文索引,刚刚有了点眉目,发现还是很实用的,这里放出入门秘籍,大家一起分享! 一,Lucene 简介 Lucene 是一个基于 Java 的全文信息检索工具包,它不是一个完整的搜索 ...

  7. 无废话ExtJs 入门教程六[按钮:Button]

    无废话ExtJs 入门教程六[按钮:Button] extjs技术交流,欢迎加群(201926085) 继上一节内容,我们在表单里加了个两个按钮"提交"与重置.如下所示代码区的第6 ...

  8. linux4.19安装教程,树莓派4安装Ubuntu 19.10的教程详解

    由于之前在raspbian上面跑opencv有些依赖包装不上,所以一些代码不能跑,就想着用Ubuntu试试.安装的过程是跟着这个视频来的: [Linux]在Raspberry Pi 4上安装完整版Ub ...

  9. Struts2的2.5.10版本找不到StrutsPrepareAndExecuteFilter过滤器 与 struts.xml文件通配符异常问题

    一.异常描述: 今天在整合ssh的时候,在配置Struts2框架之后,启动之后,项目报错抛异常:主要异常信息如下: java.lang.ClassNotFoundException: org.apac ...

最新文章

  1. 华为5G手机芯片被唱衰:美研究机构拆解6款量产机,不谈能力对标高通骁龙X50...
  2. SpringMvc解决跨域问题
  3. exe文件添加为服务
  4. UVA11349 Symmetric Matrix【数学】
  5. Java 求一段代码运行所需要的时间——模板方法设计模式
  6. matlab偏微分方程工具箱应用简介,MATLAB工具箱简介
  7. 光纤光学原理相关基础知识点
  8. 为什么要使用Typescript
  9. matplotlib柱状图上方显示数据_可视化技能之Matplotlib(上)|可视化系列01
  10. android 微信朋友圈头像,微信进阶玩法,这样设置朋友圈和头像,个性又好看
  11. HTTP、TCP网络协议知识整理
  12. eoLinker-AMS接口管理系统 项目管理教程
  13. 决策树(二)——决策树的生成
  14. 微信小程序导航栏切换页面
  15. 【好网】通信专业的大四研一研二看看:以求职经验教你选择导师专业和科研方向...
  16. 算法的时间复杂度、空间复杂度、稳定性
  17. 机械革命 Code Go 评测
  18. 1108 String复读机(JAVA)
  19. 苹果官网镜像下载地址大全(含原版、引导版、ISO/CDR)
  20. Learning: 利用Python进行数据分析 - MovieLens 数据集的探索

热门文章

  1. Day4-Mybatis框架(多表的关联查询)
  2. laya开发游戏框架--UIMgr
  3. Qt制作360安仔精灵
  4. 无人驾驶的未来 后疫情时代如何抵达
  5. facebook app
  6. php调用谷歌地图,在php mysql网站中使用谷歌地图api标记
  7. c语言编程卖鸡蛋土豆,一个鸡蛋,一个土豆,只需十几分钟,一家子的早餐就搞定了!...
  8. name ‘train_test_split‘ is not defined解决方法
  9. cfc 教程_Google API CFC
  10. TM4C123系列(一)————GPIO