转载请注明出处: http://www.liubida.com/uncategorized/lucene_analyzer_intro/
没接触过lucene的童鞋可以看看 这篇文章, 算是lucence入门比较好的文章, 读完之后可以对lucene有个简单的认识. 我也是最近有项目用到了lucene, 具体实践是对数据库的某个字段做索引, 实现了一个针对该字段匹配查询. 有点意思. 然后就趁机看了下lucene中分析器(Analyzer)的一些代码, 觉得它的分词和过滤的设计还是蛮有意思的.
lucene的分析器的功能就是对输入的数据进行分词(对文本资源进行切分, 将文本按规则切分为一个个可以进入索引的最小单位)和过滤(对最小单位进行预处理, 比如大写转小写). 在lucene中, 所有的分析器都继承自抽象类Analyzer(org.apache.lucene.analysis.Analyzer). Analyzer的代码里只定义了两个毫无意义的方法. 如下所示:
/** An Analyzer builds TokenStreams, which analyze text. It thus represents a
* policy for extracting index terms from text.
* <p>
* Typical implementations first build a Tokenizer, which breaks the stream of
* characters from the Reader into raw Tokens. One or more TokenFilters may
* then be applied to the output of the Tokenizer.
* <p>
* WARNING: You must override one of the methods defined by this class in your
* subclass or the Analyzer will enter an infinite loop.
*/
public abstract class Analyzer {
/** Creates a TokenStream which tokenizes all the text in the provided
Reader. Default implementation forwards to tokenStream(Reader) for
compatibility with older version. Override to allow Analyzer to choose
strategy based on document and/or field. Must be able to handle null
field name for backward compatibility. */
public TokenStream tokenStream(String fieldName, Reader reader)
{
// implemented for backward compatibility
return tokenStream(reader);
}
/** Creates a TokenStream which tokenizes all the text in the provided
* Reader. Provided for backward compatibility only.
* @deprecated use tokenStream(String, Reader) instead.
* @see #tokenStream(String, Reader)
*/
public TokenStream tokenStream(Reader reader)
{
return tokenStream(null, reader);
}
}
分析器的分词功能由Tokenizer的子类来完成, 过滤功能由TokenFilter的子类来完成. 同样的, 这也是两个虚无飘渺的抽象类. 下面我直接以StandardAnalyzer为实例来讲述分词和过滤的过程.
StandardAnalyzer是lucene开发包中内置的一种Analyzer的实现, 这个分析器是最容易使用也是使用很频繁的一种Analyzer, 它使用了lucene内部自带的几种分词器和过滤器.
在其代码中, 可以看到StandardAnalyzer也是继承了Analyzer, 并且实现了抽象类Analyzer的tokenStream方法. 我们注意到在这个方法里, reader首先是作为参数创建了一个分词器StandardTokenizer, 然后用这个分词器依次创建了LowerCaseFilter(大写转小写)和StopFilter(停止词过滤器)这两个过滤器. 目前为止, 基本还是一头雾水, 完全不知道分词和过滤是怎样一个过程? 其实, 到目前为止, tokenStream方法只是利用分词器, 过滤器在reader这个读入流后面铺设了一个管道而已, 真正的分词和过滤过程是在另一个地方执行的. 打个比方, reader就好像是自来水管道, tokenStream所做的只是接着这个管道又铺设了一段管道, 并且这一段的管道是用StandardTokenizer这种材质制造的, 能够对流过的文本进行切分, 然后又加上了LowerCaseFilter和StopFilter这两个过滤网. 阅读全文…