Apache Lucene 5.x 集成中文分词库 IKAnalyzer
原创
©著作权归作者所有:来自51CTO博客作者isea533的原创作品,请联系作者获取转载授权,否则将追究法律责任
Apache Lucene 5.x 集成中文分词库 IKAnalyzer
前面写过 Apache Lucene 5.x版本 示例,为了支持中文分词,我们可以使用中文分词库 IKAnalyzer。
由于IKAnalyzer使用的是4.x版本的Analyzer接口,该接口和5.x版本不兼容,因此,如果想要在5.x版本中使用IKAnalyzer,我们还需要自己来实现5.x版本的接口。
通过看源码,发现需要修改两个接口的类。
第一个是Tokenizer
接口,我们写一个IKTokenizer5x
:
/**
* 支持5.x版本的IKTokenizer
*
* @author
public class IKTokenizer5x extends Tokenizer
private IKSegmenter _IKImplement;
private final CharTermAttribute termAtt = (CharTermAttribute)this.addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAtt = (OffsetAttribute)this.addAttribute(OffsetAttribute.class);
private final TypeAttribute typeAtt = (TypeAttribute)this.addAttribute(TypeAttribute.class);
private int endPosition;
public IKTokenizer5x() {
this._IKImplement = new IKSegmenter(this.input, true);
}
public IKTokenizer5x(boolean useSmart) {
this._IKImplement = new IKSegmenter(this.input, useSmart);
}
public IKTokenizer5x(AttributeFactory factory) {
super(factory);
this._IKImplement = new IKSegmenter(this.input, true);
}
public boolean incrementToken() throws IOException {
this.clearAttributes();
Lexeme nextLexeme = this._IKImplement.next();
if(nextLexeme != null) {
this.termAtt.append(nextLexeme.getLexemeText());
this.termAtt.setLength(nextLexeme.getLength());
this.offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());
this.endPosition = nextLexeme.getEndPosition();
this.typeAtt.setType(nextLexeme.getLexemeTypeString());
return true;
} else {
return false;
}
}
public void reset() throws IOException {
super.reset();
this._IKImplement.reset(this.input);
}
public final void end() {
int finalOffset = this.correctOffset(this.endPosition);
this.offsetAtt.setOffset(finalOffset, finalOffset);
}
}
该类只是在IKTokenizer
基础上做了简单修改,和原方法相比修改了public IKTokenizer(Reader in, boolean useSmart)
这个构造方法,不在需要Reader
参数。
另一个接口就是Analyzer
的IKAnalyzer5x
:
/**
* 支持5.x版本的IKAnalyzer
*
* @author
public class IKAnalyzer5x extends Analyzer
private boolean useSmart;
public boolean useSmart() {
return this.useSmart;
}
public void setUseSmart(boolean useSmart) {
this.useSmart = useSmart;
}
public IKAnalyzer5x() {
this(false);
}
public IKAnalyzer5x(boolean useSmart) {
this.useSmart = useSmart;
}
@Override
protected TokenStreamComponents createComponents(String fieldName) {
IKTokenizer5x _IKTokenizer = new IKTokenizer5x(this.useSmart);
return new
这个类的接口由
protected TokenStreamComponents createComponents(String fieldName, Reader in)
变成了
protected TokenStreamComponents createComponents(String fieldName)
方法的实现中使用了上面创建的IKTokenizer5x
。
定义好上面的类后,在Lucene中使用IKAnalyzer5x
即可。
针对IKAnalyzer5x
我们写个简单测试:
/**
* IKAnalyzer5x 测试
*
* @author
public class IKAnalyzer5xTest
public static void main(String[] args) throws IOException {
Analyzer analyzer = new IKAnalyzer5x(true);
TokenStream ts = analyzer.tokenStream("field",
new StringReader(
"IK Analyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包。" +
"从2006年12月推出1.0版开始, IKAnalyzer已经推出了4个大版本。" +
"最初,它是以开源项目Luence为应用主体的," +
"结合词典分词和文法分析算法的中文分词组件。从3.0版本开始," +
"IK发展为面向Java的公用分词组件,独立于Lucene项目," +
"同时提供了对Lucene的默认优化实现。在2012版本中," +
"IK实现了简单的分词歧义排除算法," +
"标志着IK分词器从单纯的词典分词向模拟语义分词衍化。"));
OffsetAttribute offsetAtt = ts.addAttribute(OffsetAttribute.class);
try {
ts.reset();
while (ts.incrementToken()) {
System.out.println(offsetAtt.toString());
}
ts.end();
} finally
输出结果:
ik
analyzer
是
一个
开源
的
基于
java
语言
开发
的
轻量级
的
中文
分词
工具包
从
2006年
12月
推出
1.0版
由于结果较长,省略后面的输出内容。