Lucene系列-分析器

时间:2023-01-13 08:16:12

分析器介绍

搜索的基础是对文本信息进行分析,Lucene的分析工具在org.apache.lucene.analysis包中。分析器负责对文本进行分词、语言处理得到词条,建索引和搜索的时候都需要用到分析器,两者应当是同一个,否则没法很好的匹配。

Lucene的分析器往往包括一个分词器(Tokenizer)和多个过滤器(TokenFilter),过滤器负责对切出来的词进行处理,如去掉敏感词、转换大小写、转换单复数等。tokenStream方法中往往是先使用一个Tokenizer,接着使用多个TokenFilter,Lucene自带的StandardAnalyzer就使用了StandardTokenizer with StandardFilter, LowerCaseFilter and StopFilter。抽象基类结构图如下。

Lucene系列-分析器

注:停词-频繁使用但没有意义的词,在建索引或搜索时忽略掉。英语中的冠词、介词、连词(an/this/and),中文中的"的/也/为"。

常用分词器

以"Hello, this is a test case. 你好,这是一个测试的实例。created on 20140707"为例。

  • StandardAnalyzer:按空格、标点符号切词,中文逐字切割,忽略停词。
    [hello][test][case][你][好][这][是][一][个][测][试][的][实][例][created][20140707]
  • StopAnalyzer:空格、标点切分中英文,忽略停词,忽略数字。
    [hello][test][case][你好][这是一个测试的实例][created]
  • SimpleAnalyzer:空格、标点切分中英文,忽略数字。
    [hello][this][is][a][test][case][你好][这是一个测试的实例][created][on]
  • WhitespaceAnalyzer:空格切分中英文。
    [Hello,][this][is][a][test][case.][你好,这是一个测试的实例。created][on][20140707]

中文分词器

  • 单字分词:如StandardAnalyzer
  • 二分法:每2个字做为一个词语进行切分,可以减少每个词条后位置信息的长度。如CJKAnalyzer
    [hello][test][case][你好][这是][是一][一个][个测][测试][试的][的实][实例][created][20140707]
  • 词典分词:构造一个常用词典对文本进行词语切分,如mmseg4j的MaxWordAnalyzer
    [hello][this][is][a][test][case][你好][这是][一个][测试][的][实例][created][on][20140707]

一些技巧

如何获取切词后的Token //lucene3.5之前
Analyzer analyzer = new MaxWordAnalyzer();
TokenStream stream = analyzer.tokenStream("", new StringReader("Hello, this is a test case. " +
"你好,这是一个测试的实例。" + "created on 20140707"));
String out = "";
while (stream.incrementToken()) {
out += "[" + stream.getAttribute(TermAttribute.class).term() + "]";
}
System.out.println(out);
//lucene3.5之后
Analyzer analyzer = new StandardAnalyzer();
TokenStream stream = analyzer.tokenStream("", new StringReader("Hello, this is a test case. " +
"你好,这是一个测试的实例。" + "created on 20140707"));
String out = "";
while(stream.incrementToken()){
out += "[" + stream.getAttribute(CharTermAttribute.class).toString() + "]";
}
System.out.println(out);


mmseg4j词典

词典要求utf-8编码,可以在实例化Analyzer时指定词典路径,也可以设置mmseg.dic.path来指定词典路径,作者说自己会默认从当前目录下的data目录读取词典文件,但是我测试好像不行。如果不指定路径,倒是会从mmseg4j的jar包中的data目录加载词典。

chars.dic每行是一个单个字和对应频率,中间用空格分开,一般不用关心。猜测是不是低频率的字可以认为是乱码,丢弃不建索引呢。

units.dic每行是一个单位的字,如分、亩,用以单独切分。

words.dic是核心词库,一行一条,可以下载搜狗的词库http://www.sogou.com/labs/dl/w.html。

wordsxxx.dic是自定义词库文件。

使用mmseg4j时需要3个包:mmseg4j-core.jar包含词库文件,mmseg4j-analysis.jar是一些analysis(如MaxWordAnalyzer),mmseg4j-solr.jar是一些solr使用的功能。