Intellij idea中为lucene6配置IK Analyzer分词器

首先介绍一下IK Analyzer

IK Analyzer是一个开源的、基于java语言开发的轻量级中文分词工具包。已经推出了4个大版本。从3.0版本开始,IK Analyzer发展为面向java的公用分词组件,独立于lucene项目,同时提供了对lucene的默认优化实现。在2012版本中,IK Analyzer实现了简单的分词歧义排除算法,标志着IK分词器从单纯的词典分词向模拟语义分词衍化。支持细粒度ik_max_word和智能分词ik_smart两种切分模式。

其项目地址为:https://code.google.com/archive/p/ik-analyzer/downloads

下载2012版本source,可以看到其是兼容lucene3.1以上版本的

lucene6.0使用IK分词器需要修改IKAnalyzer和IKTokenizer。

 

IKAnalyzer的修改,重写最新版本的CreateComponents方法;重载Analyzer接口

public class IKAnalyzer6x extends Analyzer {
	private boolean useSmart;

	public boolean useSmart() {
		return useSmart;
	}

	public void setUseSmart(boolean useSmart) {
		this.useSmart = useSmart;
	}

	// IK分词器Lucene Analyzer接口实现类;默认细粒度切分算法
	public IKAnalyzer6x() {
		this(false);
	}

	// IK分词器Lucene Analyzer接口实现类;当为true时,分词器进行智能切分
	public IKAnalyzer6x(boolean useSmart) {
		super();
		this.useSmart = useSmart;
	}

	// 重写最新版本的createComponents;重载Analyzer接口,构造分词组件
	@Override
	protected TokenStreamComponents createComponents(String fieldName) {
		Tokenizer _IKTokenizer = new IKTokenizer6x(this.useSmart());
		return new TokenStreamComponents(_IKTokenizer);
	}
}

IKTokenizer的修改,要实现最新的Tokenizer接口

public class IKTokenizer6x extends Tokenizer {
	// IK分词器实现
	private IKSegmenter _IKImplement;
	// 词元文本属性
	private final CharTermAttribute termAtt;
	// 词元位移属性
	private final OffsetAttribute offsetAtt;
	// 词元分类属性(该属性分类参考org.wltea.analyzer.core.Lexeme中的分类常量)
	private final TypeAttribute typeAtt;
	// 记录最后一个词元的结束位置
	private int endPosition;

	// Lucene 6.x Tokenizer适配器类构造函数;实现最新的Tokenizer接口
	public IKTokenizer6x(boolean useSmart) {
		super();
		offsetAtt = addAttribute(OffsetAttribute.class);
		termAtt = addAttribute(CharTermAttribute.class);
		typeAtt = addAttribute(TypeAttribute.class);
		_IKImplement = new IKSegmenter(input, useSmart);
	}

	@Override
	public boolean incrementToken() throws IOException {
		// 清除所有的词元属性
		clearAttributes();
		Lexeme nextLexeme = _IKImplement.next();
		if (nextLexeme != null) {
			// 将Lexeme转成Attributes
			// 设置词元文本
			termAtt.append(nextLexeme.getLexemeText());
			// 设置词元长度
			termAtt.setLength(nextLexeme.getLength());
			// 设置词元位移
			offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition());
			// 记录分词的最后位置
			endPosition = nextLexeme.getEndPosition();
			// 记录词元分类
			typeAtt.setType(nextLexeme.getLexemeText());
			// 返会true告知还有下个词元
			return true;
		}
		// 返会false告知词元输出完毕
		return false;
	}

	@Override
	public void reset() throws IOException {
		super.reset();
		_IKImplement.reset(input);
	}

	@Override
	public final void end() {
		int finalOffset = correctOffset(this.endPosition);
		offsetAtt.setOffset(finalOffset, finalOffset);
	}
}

以上都来自姚潘《从lucene到ElasticSearch全文检索实战》

如果在使用中出现错误

java.lang.AssertionError: TokenStream implementation classes or at least their incrementToken() implementation must be final
那么为IKTokenizer6x class 加入final关键字

 

如何把lucene ik analyzer引入到我的maven项目中呢?

当然,基础是pom.xml中加入了lucene依赖

<!--搜索引擎lucene-->
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-core</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-analyzers-common</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-queries</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-highlighter</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-queryparser</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>org.apache.lucene</groupId>
	<artifactId>lucene-analyzers-smartcn</artifactId>
	<version>${lucene.version}</version>
</dependency>
<dependency>
	<groupId>com.belerweb</groupId>
	<artifactId>pinyin4j</artifactId>
	<version>2.5.1</version>
</dependency>

接下来需要把IK Analysis使用的jar包加入到Intellij idea项目中

通过Project Structure – module –Dependencies,加入对应文件夹

其lib下放我们下载的IK Analyzer jar包

接下来在项目中新建文件夹ik,里面放我们重写的IKAnalyzer6x及IKTokenizer6x java文件

最后把词典等配置文件放到classpath路径下,即resources中

这样我们在程序中就可以使用IKAnalyzer6x分词器了

 

我们在pom中添加了lucene官方的lucene-analyzers-smartcn分词器

下面程序比较了IK分词与Smartcn分词的效果

public class IkVSSmartcn {

    
    private static String str2 = "IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。";    

    public static void main(String[] args) {
        Analyzer analyzer = null;        

        System.out.println("-------------------------------------------");
        System.out.println("句子2:"+str2);
        System.out.println("SmartChineseAnalyzer分词结果:");
        analyzer = new SmartChineseAnalyzer();
        printAnalyzer(analyzer, str2);
        System.out.println("IKAnalyzer分词结果:");
        analyzer = new IKAnalyzer6x(true);
        printAnalyzer(analyzer, str2);
      
    }

    public static void printAnalyzer(Analyzer analyzer, String str) {
        StringReader reader = new StringReader(str);
        //处理单个字符组成的字符流,读取Reader对象中的数据,处理后转换成词汇单元
        TokenStream tokenStream = analyzer.tokenStream(str, reader);
        // 清空流
        try {
            tokenStream.reset();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //CharTermAttribute -- The term text of a Token.
        //Returns the instance of the passed in Attribute contained in this AttributeSource
        CharTermAttribute attribute = tokenStream.getAttribute(CharTermAttribute.class);

        try {
            while (tokenStream.incrementToken()) {
                System.out.print(attribute.toString()+"|");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println();
    }
}

结果

句子2:IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。
SmartChineseAnalyzer分词结果:
ikanalyz|是|一个|开|源|的|基于|java|语言|开发|的|轻量级|的|中文|分词|工具包|
IKAnalyzer分词结果:
加载扩展词典:ext.dic
加载扩展停止词典:stopword.dic
加载扩展停止词典:ext_stopword.dic
ikanalyzer|开源|java|语言|开发|轻量级|中文|分词|工具包|

看起来IK分词效果更好

猜你喜欢

转载自blog.csdn.net/u013905744/article/details/81130927
今日推荐