首页 > 其他 > 详细

《Lucene in Action 第二版》第4章节 学习总结 -- Lucene中的分析

时间:2014-03-26 07:31:46      阅读:412      评论:0      收藏:0      [点我收藏+]

通过第四章的学习,可以了解lucene的分析过程是怎样的,并且可以学会如何使用lucene内置分析器,以及自定义分析器。下面是具体总结

1. 分析(Analysis)是什么?

在lucene中,分析就是指:将域(Field)文本转换成最基本的索引表示单元---项(Term)的过程。而项(Term)又是由语汇单元(Token)以及它所属的域名组合而成的。

在索引过程中存在分析(IndexWriter的初始化中需要放入一个Analyzer的实例;并且如果要使Analyzer生效,则需要使用Index.ANALYZED或者Index.ANALYZED_NO_NORMS属性);在利用QueryParser进行搜索的过程中也存在分析(QueryParser的初始化中也需要放入一个Analyzer的实例)。

分析是通过分析器(Analyzer)进行的。Lucene推荐,在索引和搜索期间,使用相同的Analyzer进行处理。

分析器不能做什么?分析器的前提是域已经分好了。因此必须在使用分析器之前,先把文本预先解析并形成域。分析器内不可以创建新的域。

2. Analyzer的作用,就是分析输入的字符文件。其主要的过程如下:

通过调用某个具体Analyzer子类的TokenStream(String fieldName, Reader reader)(reader里面就包含了输入的要解析的文本,fieldname可以为空,即"";但是在不为空时,它起到什么作用呢?),将输入的文本分析成Term。而在TokenStream内部,则可以:1.首先用一个具体的Tokennzer对象从输入的文本创建初始语汇单元序列;2.然后用任意数量(可以是0个)的tokenFilter对象来修改这些语汇单元。最终产生的就是语汇单元流:TokenStream。

3. 语汇单元流是由各个语汇单元组成的。而每个语汇单元的组成,包括了:文本值本身+其他一些元数据。这些都可以理解为该语汇单元的属性,它们是可以通过具体对象实例的API方法得到的。具体为:

TermAttribute ---- 语汇单元对应的文本,通过 .term()方法就可以得到具体文本值

PositionIncrementAttribute --- 本语汇单元相对于前一个语汇单元的位置增量(默认值是1)。通过. getPositionIncrement()可以得到位置增量的值。

OffsetAttriute  --- 语汇单元的起始字符和终止字符的偏移量。其中起始字符偏移量表示的是语汇单元的文本的起始字符在原始文本中的位置,通过.startOffset()得到;而终止字符偏移量则表示语汇单元的文本终止字符的下一个位置。通过.endOffset()得到

TypeAttribute --- 语汇单元类型(默认是 word)。通过.type()得到。

FlagsAttribute --- 自定义标志位 (具体怎么用,尚不清楚)

PayloadAttribute --- 每个语汇单元的byte[]类型有效负载(具体怎么用,尚不清楚)

4. Lucene的内置分析器是需要熟练掌握和运用的。而且书上说,适用范围最广的分析器是StandardAnalyzer

5. 如何创建自己的分析器:一般构建自定义分析器,需要定义Analyzer子类以及自定义TokenFilter;而Tokenizer一般是用现成的。常规套路如下:

A. 自定义一个Analyzer,继承自Analyzer,即书上的例子:

public class MetaphoneReplacementAnalyzer extends Analyzer {

        @Override

        public TokenStream tokenStream(String fieldName, Reader reader)   {

                // TODO Auto-generated method stub

               returnnew MetaphoneReplacementFilter(new LetterTokenizer(reader));

        }

}

B. 自定义TokenFilter(可以是一个或者多个)。在自定义的TokenFilter中,一般就要利用语汇单元的各种属性来对语汇单元进行过滤了。并且还要实现在TokenFilter中唯一要实现的方法:incrementToken()

public class MetaphoneReplacementFilter extends TokenFilter {

        public static final String METAPHONE = "metaphone";

        private Metaphone metaphoner = new Metaphone();

        private TermAttribute termAttr;

       private TypeAttribute typeAttr;

       protected MetaphoneReplacementFilter(TokenStream input) {

                super(input);

                 // TODO Auto-generated constructor stub

                termAttr = addAttribute(TermAttribute.class);

               typeAttr = addAttribute(TypeAttribute.class);

        }

        @Override

         public boolean incrementToken() throws IOException {

                 // TODO Auto-generated method stub

                if(!input.incrementToken()) {

                          return false;

                }

               String encoded;

               encoded = metaphoner.encode(termAttr.term());

               termAttr.setTermBuffer(encoded);

               typeAttr.setType(METAPHONE);

               return true;

        }

}

6. 同时,要知道:网络上有很多现成的分析器实现,可以借用的

7. 好东西:PerFieldAnalyzerWrapper --- 具体怎么好,后面再补充

《Lucene in Action 第二版》第4章节 学习总结 -- Lucene中的分析,布布扣,bubuko.com

《Lucene in Action 第二版》第4章节 学习总结 -- Lucene中的分析

原文:http://www.cnblogs.com/lagujw/p/3616726.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!