Lucene实现自己的英文空格小写分词器
看一下继承图,Tokenizer和TokenFilter都是继承于TokenStream,TokenStream继承了AttributeSource

package com.lucene.demo.analizer;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.util.Attribute;
import org.apache.lucene.util.AttributeImpl;
import org.apache.lucene.util.AttributeReflector;
import java.io.IOException;
public class SansamAnalyzer extends Analyzer{
    /**
     *
     */
    @Override
    protected TokenStreamComponents createComponents(String fieldName) {
        //装饰器模式,将分出的词项用filter进行处理,可以链式装饰实现多个filter
        MyTokenizer myTokenizer = new MyTokenizer();
        MyLowerCaseTokenFilter myLowerCaseTokenFilter = new MyLowerCaseTokenFilter(myTokenizer);
        return new TokenStreamComponents(myTokenizer, myLowerCaseTokenFilter);
    }
    public static class MyTokenizer extends Tokenizer{
        //调用AttributeSource-addAttribute方法
        //维护了一个attributes Map,实现可复用
        //private final Map<Class<? extends Attribute>, AttributeImpl> attributes;
        //private final Map<Class<? extends AttributeImpl>, AttributeImpl> attributeImpls;
        MyAttribute attribute = this.addAttribute(MyAttribute.class);
        char[] buffer = new char[255];
        int length = 0;
        int c;
        @Override
        public boolean incrementToken() throws IOException {
            //进行分析处理逻辑
            clearAttributes();
            length = 0;
            while (true){
                c = this.input.read();
                if(c == -1){
                    if(length > 0){
                        this.attribute.setChar(buffer,length);
                        return true;
                    }else {
                        return false;
                    }
                }
                if(Character.isWhitespace(c)){
                    if(length > 0){
                        this.attribute.setChar(buffer,length);
                        return true;
                    }
                }
                buffer[length++] = (char)c;
            }
        }
    }
    public static class MyLowerCaseTokenFilter extends TokenFilter{
        public MyLowerCaseTokenFilter(TokenStream s){
            super(s);
        }
        MyAttribute attribute = this.addAttribute(MyAttribute.class);
        @Override
        public boolean incrementToken() throws IOException {
            //获取一个分词项进行处理
            boolean b = this.input.incrementToken();
            if (b){
                char[] chars = this.attribute.getChar();
                int length = this.attribute.getLength();
                if(length > 0){
                    for (int i = 0; i < length; i++) {
                        chars[i] = Character.toLowerCase(chars[i]);
                    }
                }
            }
            return b;
        }
    }
    /**
     * 自定义Attribute属性接口 继承Attribute
     */
    public static interface MyAttribute extends Attribute {
        void setChar(char [] c, int length);
        char [] getChar();
        int getLength();
        String getString();
    }
    /**
     * 必须使用interface+Impl 继承AttributeImpl
     */
    public static class MyAttributeImpl extends AttributeImpl implements MyAttribute {
        char [] term = new char[255];
        int length = 0;
        @Override
        public void setChar(char[] c, int length) {
            this.length = length;
            if(c.length > 0){
                System.arraycopy(c,0,term,0,length);
            }
        }
        @Override
        public char[] getChar() {
            return term;
        }
        @Override
        public int getLength() {
            return length;
        }
        @Override
        public String getString() {
            if(length > 0){
                return new String(term,0,length);
            }
            return null;
//            return new String(term);  //不能直接返回 因为长度问题 默认255字符
        }
        @Override
        public void clear() {
            term = null;
            term = new char[255];
            this.length = 0;
        }
        @Override
        public void reflectWith(AttributeReflector reflector) {
        }
        @Override
        public void copyTo(AttributeImpl target) {
        }
    }
    public static void main(String[] args) {
        String text = "Hello World A b C";
        try(SansamAnalyzer analyzer = new SansamAnalyzer();
            //调用tokenStream()时 会先得到TokenStreamComponents对象 得到了MyLowerCaseTokenFilter 对象 观察其构造方法及此方法的返回值
            TokenStream stream =  analyzer.tokenStream("title",text);){
            MyAttribute attribute = stream.getAttribute(MyAttribute.class);
            stream.reset();
            while (stream.incrementToken()){
                System.out.print(attribute.getString()+" | ");
            }
            stream.end();
        }catch (Exception e){
                e.printStackTrace();
        }
    }
}
												
											Lucene实现自己的英文空格小写分词器的更多相关文章
- lucene整理3 -- 排序、过滤、分词器
		
1. 排序 1.1. Sort类 public Sort() public Sort(String field) public Sort(String field,Boolean reverse ...
 - Lucene的中文分词器IKAnalyzer
		
分词器对英文的支持是非常好的. 一般分词经过的流程: 1)切分关键词 2)去除停用词 3)把英文单词转为小写 但是老外写的分词器对中文分词一般都是单字分词,分词的效果不好. 国人林良益写的IK Ana ...
 - Lucene介绍及简单入门案例(集成ik分词器)
		
介绍 Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和 ...
 - elasticsearch  分析器 分词器
		
参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html 在全文搜索(Fu ...
 - Elasticsearch之文档的增删改查以及ik分词器
		
文档的增删改查 增加文档 使用elasticsearch-head查看 修改文档 使用elasticsearch-head查看 删除文档 使用elasticsearch-head查看 查看文档的三种方 ...
 - Restful认识和 IK分词器的使用
		
什么是Restful风格 Restful是一种面向资源的架构风格,可以简单理解为:使用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT)描述操作. 使用Restful的好处: 透 ...
 - IK分词器 原理分析 源码解析
		
IK分词器在是一款 基于词典和规则 的中文分词器.本文讲解的IK分词器是独立于elasticsearch.Lucene.solr,可以直接用在java代码中的部分.关于如何开发es分词插件,后续会有文 ...
 - ElasticSearch-IK分词器和集成使用
		
1.查询存在问题分析 在进行字符串查询时,我们发现去搜索"搜索服务器"和"钢索"都可以搜索到数据: 而在进行词条查询时,我们搜索"搜索"却没 ...
 - 三、Solr多核心及分词器(IK)配置
		
多核心的概念 多核心说白了就是多索引库.也可以理解为多个"数据库表" 说一下使用multicore的真实场景,比若说,产品搜索和会员信息搜索,不使用多核也没问题,这样带来的问题是 ...
 
随机推荐
- leetcode978
			
class Solution(object): def maxTurbulenceSize(self, A: 'List[int]') -> int: n = len(A) if n == 1: ...
 - xcode9.4 报错 error:The resource could not be loaded because the App Transport Security policy requires the use of a secure connection.
			
原因 http | https 协议 不能正常使用 找到的解决方案 但是在字段名上有了变化,不过复制进去 还是会自动选择对应的 解决办法 1. 在Info.plist中添加 App Transpor ...
 - Image Storage
 - 阿里云ossfs配置
			
Github:https://github.com/aliyun/ossfs/wiki Root账户卸载:umount /挂载目录非root用户要卸载目录,请用:fusermount -u your_ ...
 - linux命令行下xlsx转换成pdf或csv的笔记
			
使用libreoffice(可以用yum直接安装,占用了4xxM磁盘空间...) 然后命令行执行: 转换成csv,支持utf-8中文编码: libreoffice --invisible --con ...
 - MySQL 权限相关
			
# ============================= mysql 权限相关 =====================================================gran ...
 - 使用百度ocr接口识别验证码
			
#!/usr/bin/env python #created by Baird from aip import AipOcr def GetCaptchaV(filename): APP_ID = ' ...
 - [转] ESXI6.5 误将硬盘阵列卡配置为passthru直通模式后, 找不到硬盘的问题
			
There is no easy way to do it, it seems. So I wanted to say that I couldn't afford to do an upgrade ...
 - Nagios监控
			
1.Nagios监控软件 Nagios是一款开源的免费网络监视工具,能有效监控Windows.Linux和Unix的主机状态,交换机路由器等网络设置,打印机等.在系统或服务状态异常时发出邮件或短信报警 ...
 - HTTP协议中request和response常用方法
			
一.request的常用方法:1.获取请求的方式 getMethod()2.目录的路径 getContextPath()3.获取servlet路径 getServletString()4.获得get请 ...