Analysis(分析)是从要索引的文本中提取term(索引项)的过程。Lucene中,分析是由实现Analyzer抽象类的分析器来实现。分析器分析要索引的文本,剔出一些没有意义的词(如“the、a”,称为stop词),提取要索引的词并进行一定的转化,最终形成一个Token流(TokenStream)。对于西方语言,分析一般还有单词小写化(normalizing)、不同单词形式的统一化(如一个单词,有名词形式也有动词形式,对于索引来讲,他们都应该是一个词)(stemming和lemmatization),对于东亚语言,主要是分词,就是首先从文本中提取词。
分析器在索引和QueryParser中使用,两个过程尽量使用同一种分析器。整个索引过程可以指定一种分析器,对于某个索引文档也可以指定单独的分析器。对于Field,通过使用PerFieldAnalyzerWrapper类,可以对其指定单独的分析器。不过,Lucene中提供的分析器忽视Field,除非你所使用的分析器用到了Field,否则对Field指定分析器是没有意义的。
分析器只对纯文本进行分析,如果对其他类型的文档比如word、pdf等,应该先使用解析器对文档进行解析,再对解析的文本内容进行分析。
(一)分析器
Analyzer类是分析器的抽象父类,所有分析器都是它的子类并且要实现tokenStream方法。
public TokenStream tokenStream(String fieldName, Reader reader)
fieldName参数在Lucene提供的分析器中都没有用到。
(二)Token是分析后的基本元素,它由以下几项组成:
文本值
起始偏移量:文本第一字符在文档中的起始位置
末偏移量:文本最后一个字母的位置+1
类型 默认为“word”
位置增量:起始偏移量与前一个Token末偏移量之差,默认为1。
Token去掉类型、始和末偏移量,就成了Index中的term。
(三)分析器形成TokenStream有两种形式:分词(Tokenizer)和过滤(TokenFilter)。分词是从输入文本流中提取Token,形成Token流;过滤是对Token流(TokenStream)进行再处理,形成新的TokenStream。
TokenStream类是对Token类的遍历抽象类。Tokenizer和TokenFilter是TokenStream类的子类,这两个类都不能直接使用,只能使用从这两个类继承的子类。
(四)Lucene自带的StandardAnalyzer可以处理中文,其他的分析器只能处理英文。扩展库中,org.apache.lucene.analysis.cn包含中文一元分词算法的分析器,org.apache.lucene.analysis.cjk包含二元分词算法的分析器,这两个都可以处理中文。
在网上找了几个免费的中文分词包,发现IKAnalyszer不错,分词率高,字典是文本形式,可以直接添加新词。
IKAnalyszer包括两种分析器,采用正反向全切分算法的IKAnalyszer和基于最大匹配算法MIK_CAnalyzer,前者能找出分析文本中所有能找到的词,主要用于索引(index);后者找到的词比前者要少,主要用于用户搜索语句分析(QueryPraser)。