Lucene中Analyzer处理过程详解

最近做项目中应用到了Lucene做搜索应用,于是顺便学习它的源代码。下面就将学习到的“Lucene分析器分析过程”与大家分享!限于水平,错误难免。请大家不吝赐教。让拍砖来的更猛烈些,文章为原创,参照Lucen in Action中

部分内容,如需要转载,请与作者联系,或标明来源。谢谢!


一、先看看编写的Demo及运行效果,总览一下。

private static Log log = LogFactory.getLog(AnalyzerDemo.class);
	public static void main(String[] args) throws IOException{
		Analyzer analyzer = new SimpleAnalyzer();
		TokenStream stream = analyzer.reusableTokenStream(null, new StringReader("Programminged is fun,by the way,do you like dog?"));
		while(true){
			Token token = stream.next();
			if(null == token){
				log.info("完毕!");
				break;
			}
			log.info(new String(token.termBuffer()) + " 起始位置:" + token.startOffset() + " 结束位置:" + token.endOffset());
		}
	}


   程序运行后控制台效果:

0    [main] INFO  test.lucene.AnalyzerDemo  - programminged 起始位置:0 结束位置:13
16   [main] INFO  test.lucene.AnalyzerDemo  - is 起始位置:14 结束位置:16
16   [main] INFO  test.lucene.AnalyzerDemo  - fun 起始位置:17 结束位置:20
16   [main] INFO  test.lucene.AnalyzerDemo  - by 起始位置:21 结束位置:23
16   [main] INFO  test.lucene.AnalyzerDemo  - the 起始位置:24 结束位置:27
16   [main] INFO  test.lucene.AnalyzerDemo  - way 起始位置:28 结束位置:31
16   [main] INFO  test.lucene.AnalyzerDemo  - do 起始位置:32 结束位置:34
16   [main] INFO  test.lucene.AnalyzerDemo  - you 起始位置:35 结束位置:38
16   [main] INFO  test.lucene.AnalyzerDemo  - like 起始位置:39 结束位置:43
16   [main] INFO  test.lucene.AnalyzerDemo  - dog 起始位置:44 结束位置:47
16   [main] INFO  test.lucene.AnalyzerDemo  - 完毕!


  以上代码中,使用SimpleAnalyzer进行分析。它内置使用LowerCaseTokenizer 。至于分析的结果,我将在下文结合Lucene源代码详细描述。



二、让我们看一下UML图,UML图画的可能比较粗糙一些


这个图是SimpleAnalyzer的架构图,旁边给了说明,就不再赘述了。值的注意的是,simpleAnalyzer两个方法,返回值都是TokenStream,这个类就是我刚才提到的LowerCaseTokenizer的超类。

为了方便大家观看它的结构。下面将给出它的架构图,如下:


三、分析处理过程

      上述代码中,我们构建了一个LowerCaseTokenizer,通过构造方法,将StringReader传递到Tokeinzer的 protected Reader input 中。

       接着调用TokenStrem的next()方法,这个方法主要是构建Token的,在这个方法内部,它调用CharTokenizer的重载方法,下面主要讲讲Chartokenizer.next(Token token)

       1)程序给出了一个死循环,while(true),在这个循环内部,逐个调字串分析,调用抽象方法isTokenChar,如果返回false,则break循环。我们上例中,碰到“空格”后就跳出。

       2)如果是字符串,即时isTokenChar返回为真的时候,记录下这个字串到char[] buffer中。

       3)char[] buffer在初始化时,设置长度为10,如果超出10,比如我们的"Programminged"(为了超出10个字串,说明问题,构建了一个错误的单词,见笑了。)则扩充长度*2

          这段代码在Token中,size *= 2;
                                        char[] newBuffer = new char[size];
                                        System.arraycopy(termBuffer, 0, newBuffer, 0, termBuffer.length);

       4)包装Token,内容不但有每个Token的内容,还有它的起始、结束位置。谓之原数据。这将在高亮显示时使用。


四、Analyzer将输入源进行分析,通过DocumentsWriter进行写索引。

      见代码:

            // Tokenize field and add to postingTable
            stream = analyzer.reusableTokenStream(fieldInfo.name, reader);

     上述是Lucene自带的SimpleAnalyzer分析处理过程,我们可以扩充Analyzer 类,扩建自已的中文分词处理器。

 

你可能感兴趣的:(数据结构,Lucene,UML)