您的位置:首页 > 运维架构 > Apache

Apache Lucene 5.x 集成中文分词库 IKAnalyzer

2015-12-05 16:24 441 查看

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 liuzh
*/
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 liuzh
*/
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 TokenStreamComponents(_IKTokenizer);
}
}


这个类的接口由

protected TokenStreamComponents createComponents(String fieldName, Reader in)


变成了

protected TokenStreamComponents createComponents(String fieldName)


方法的实现中使用了上面创建的
IKTokenizer5x


定义好上面的类后,在Lucene中使用
IKAnalyzer5x
即可。

针对
IKAnalyzer5x
我们写个简单测试:

/**
* IKAnalyzer5x 测试
*
* @author liuzh
*/
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 {
ts.close();
}
}
}


输出结果:

ik

analyzer



一个

开源



基于

java

语言

开发



轻量级



中文

分词

工具包



2006年

12月

推出

1.0版

由于结果较长,省略后面的输出内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息