zoukankan      html  css  js  c++  java
  • Lucene 分词

    在Lucene中很多数据是通过Attribute进行存储的

     步骤是同过TokenStrem获取文本信息流

    TokenStream stream = a.tokenStream("content", new StringReader(str)); (a:指的是Analyzer)

    而在这里对这个由不同的分词的话之需要实现Analyer,并重写里面的tokenStream 方法

    public TokenStream tokenStream(String fieldName, Reader reader) {
    Dictionary dic = Dictionary.getInstance("F:\CheckOut\Lucene\03_lucene_analyzer\mmseg4j-1.8.4\data");

    return new MySameTokenFilter(new MMSegTokenizer(new MaxWordSeg(dic), reader),samewordContext);
    }

    然后这里获取他的Tokenizer 并可以实现自己的过滤器,以及相应的同义词删减

    public class MySameTokenFilter extends TokenFilter{
    
        private CharTermAttribute cta = null;
        private PositionIncrementAttribute pia = null;
        private AttributeSource.State current = null;
        private Stack<String> sames = null;
        private SamewordContext samewordContext;
        
        protected MySameTokenFilter(TokenStream input,SamewordContext samewordContext) {
            super(input);
            cta = this.addAttribute(CharTermAttribute.class);
            pia = this.addAttribute(PositionIncrementAttribute.class);
            sames = new Stack<String>();
            this.samewordContext=samewordContext;
        }
    
        /**
         * 思想如下:
         * 其实每个同义词都要放在CharTermAttribute里面,但是如果直接cta.append("大陆");的话
         * 那会直接把原来的词和同义词连接在同一个语汇单元里面[中国大陆],这样是不行的
         * 要的是这样的效果[中国][大陆]
         * 那么就要在遇到同义词的时候把当前的状态保存一份,并把同义词的数组放入栈中,
         * 这样在下一个语汇单元的时候判断同义词数组是否为空,不为空的话把之前的保存的一份状态
         * 还原,然后在修改之前状态的值cta.setEmpty(),然后在把同义词的值加入cta.append("大陆")
         * 再把位置增量设为0,pia.setPositionIncrement(0),这样的话就表示是同义词,
         * 接着把该同义词的语汇单元返回
         */
        @Override
        public boolean incrementToken() throws IOException {
            System.out.println("yaobo");
            while(sames.size() > 0){
                //将元素出栈,并获取这个同义词
                String str = sames.pop();
                //还原状态
                restoreState(current);
                cta.setEmpty();
                cta.append(str);
                //设置位置
                pia.setPositionIncrement(0);
                return true;
            }
            if(!input.incrementToken()) return false;
            if(addSames(cta.toString())){
                //如果有同义词将当前状态先保存
                current = captureState();
            }
            return true;
        }
    /*    
     * 使用这种方式是不行的,这种会把的结果是[中国]替换成了[大陆]
     * 而不是变成了[中国][大陆]
        @Override
        public boolean incrementToken() throws IOException {
            if(!input.incrementToken()) return false;
            if(cta.toString().equals("中国")){
                cta.setEmpty();
                cta.append("大陆");
            }
            return true;
        }
    */
        private boolean addSames(String name){
            
            String[] sws = samewordContext.getSamewords(name);
            if(sws != null){
                for(String s : sws){
                    sames.push(s);
                }
                return true;
            }
            return false;
        }
    }

    其思想如下

    然后通过不同的Attribute进行分割

    TokenStream stream = a.tokenStream("content", new StringReader(str));
    //位置增量
    PositionIncrementAttribute pia = stream.addAttribute(PositionIncrementAttribute.class);
    //偏移量
    OffsetAttribute oa = stream.addAttribute(OffsetAttribute.class);
    //词元
    CharTermAttribute cta = stream.addAttribute(CharTermAttribute.class);
    //分词的类型
    TypeAttribute ta = stream.addAttribute(TypeAttribute.class);

  • 相关阅读:
    System.Diagnostics.Conditional 的妙用 -- 把文档放在代码中
    UGUI 特效怎样在UI上裁剪
    通过GL函数处理图片以及其它相关功能
    每次都能让人头大的 Shader -- 从整合说起
    每次都能让人头大的 Shader -- 从一次简单的功能说起
    由于闭包引起的内存泄漏
    较为激进的基础框架
    UGUI 逻辑以及实用性辅助功能
    单相机做分屏混合
    AssetBundleMaster_ReadMe_EN
  • 原文地址:https://www.cnblogs.com/yaobolove/p/6896883.html
Copyright © 2011-2022 走看看