分析器介绍
搜索的基础是对文本信息进行分析,Lucene的分析工具在org.apache.lucene.analysis包中。分析器负责对文本进行分词、语言处理得到词条,建索引和搜索的时候都需要用到分析器,两者应当是同一个,否则没法很好的匹配。
Lucene的分析器往往包括一个分词器(Tokenizer)和多个过滤器(TokenFilter),过滤器负责对切出来的词进行处理,如去掉敏感词、转换大小写、转换单复数等。tokenStream方法中往往是先使用一个Tokenizer,接着使用多个TokenFilter,Lucene自带的StandardAnalyzer就使用了StandardTokenizer with StandardFilter, LowerCaseFilter and StopFilter。抽象基类结构图如下。
注:停词-频繁使用但没有意义的词,在建索引或搜索时忽略掉。英语中的冠词、介词、连词(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();//lucene3.5之后
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);
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使用的功能。