全文索引(三)lucene 分词 Analyzer

分词: 将reader通过阅读对象Analyzer字处理,得到TokenStream处理流程被称为分割。

该解释可能是太晦涩。查看示例,这个东西是什么感性的认识。


样品:一段文本“this is jack’s house”,经过分词器处理之后得到可能为jack 、house。

这个过程中:this is 称之为停留词。这种词是不会被存入索引文件的。这个主要通过StopAnalyzer分词器来实现,后面我们会讲。
jack’s 被转换为 jack 。诸如此类coming会被转换为come。全部的形式都会被最为原始的状态。


分词的过程主要由Analyzer类解析实现,而Analyzer通过调用TokenStream及其两个子类TokenFilter、Tokenizer来实现。

总体的结构类图例如以下

这里写图片描写叙述

一. Analyzer

这里写图片描写叙述

经常使用的有:

SimpleAnalyzer: 将查询语句转换为语素单元时完毕转换为小写的操作。

StandardAnalyzer :最为经常使用的智能分词器,通过这两个LowerCaseFilter和StopFilterTokenStream。能完毕诸如邮件、字母分析处理。

WhitespaceAnalyzer :以空格为分词符进行分析处理。

如:I am coder—-这里写图片描写叙述

Lucene3.5 有9种分词器。继承Analyzer抽象类内部通过tokenStream(String fieldName, Reader reader)方法来处理读取的查询数据,Analyzer和不同子类分词器的实现。应该能看到组合模式的设计。

二. TokenStream

经过分词、过滤处理后的结果流。

主要通过public abstract boolean incrementToken() throws IOException 方法来实现分词后各语素的处理读取操作。
tokenFilter 和 Tokenizer两个子类来实现 去停留词和得到分词单元。

#三. 分词一般处理流程#

这里写图片描写叙述

分词器主要流程

  • 第一步:reader对象读取分词数据
  • 第二步:Tokenier 负责将一组数组分解为一个个的单元
    如:I am coder—-这里写图片描写叙述
  • 第三步:经过多重过滤器对分词数据进行过滤操作。

    过滤的作用是去除停留词,并形态还原,统一大写和小写等。
    去除停留词: 就是去除相似in of this 等没有确切含义的词。这些不会被当做分词单元。形态还原则是将过去分词、过去式这种词还原为原来的形态。如:termming-term。

demo

public void createToken(String strContent,Analyzer analyer){
        try {
            //1.创建TokenStream对象
            TokenStream tokenStream=analyer.tokenStream("", new StringReader(strContent));
            //charTermAttribute 保存了分词中的各个语素单元
            CharTermAttribute cta=tokenStream.addAttribute(CharTermAttribute.class);
            //PositionIncrementAttribute 保存分词各个语素单元的位置信息
            PositionIncrementAttribute pta=tokenStream.addAttribute(PositionIncrementAttribute.class);
            //OffsetAttribute 保存各语素单元的偏移量
            OffsetAttribute oab=tokenStream.addAttribute(OffsetAttribute.class);

            //读取分词单元的信息
            while(tokenStream.incrementToken()){

                System.out.println("----------cta---------="+cta);
                System.out.println("----------pta---------="+pta);
                System.out.println("----------oab---------="+oab);

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
private LuceneAnalyzerUtil luceneAnalyzer=null;

    public testAnalyzer(){

        luceneAnalyzer=new LuceneAnalyzerUtil();

    }
    @Test
    public void testCreateToken(){
        //标准分词器。作为一般标准的分词器有自己智能的一面,
        Analyzer analyzer1=new StandardAnalyzer(Version.LUCENE_35);
        Analyzer analyzer2=new StopAnalyzer(Version.LUCENE_35);
        Analyzer analyzer3=new ClassicAnalyzer(Version.LUCENE_35);
        Analyzer analyzer4=new KeywordAnalyzer();
        Analyzer analyzer5=new WhitespaceAnalyzer(Version.LUCENE_35);

        luceneAnalyzer.createToken("I am human,I am special", analyzer1);
        luceneAnalyzer.createToken("I am human,I am special", analyzer2);
        luceneAnalyzer.createToken("I am human,I am special", analyzer3);
        luceneAnalyzer.createToken("I am human,I am special", analyzer4);
        luceneAnalyzer.createToken("I am human,I am special", analyzer5);

    }

总的来讲,lucene的分词器主要做了一个什么样的工作呢?从查询语句分解为一个个查询单元的工作。

这么做的目的是为了lucene在查询时候更好的细粒度的去匹配已创建的索引文件。

posted @ 2015-12-08 19:15  hrhguanli  阅读(263)  评论(0编辑  收藏  举报