IKAnalyzer分词器支持Lucene5+/Solr5+
IKAnalyzer分词器支持Lucene5+/Solr5+
God_Seven 发表于3年前
IKAnalyzer分词器支持Lucene5+/Solr5+
  • 发表于 3年前
  • 阅读 1252
  • 收藏 6
  • 点赞 1
  • 评论 3

腾讯云 技术升级10大核心产品年终让利>>>   

摘要: 公司内部项目使用了IK分词器,原本使用的是Solr4.10.2,对应的Lucene也还是4,心血来潮想升级最新版的Solr5.1,于是IK的不支持问题就来了····

升级Solr5.1的过程就不描述了,从4.10.2升上来,基本没有任何其他问题。但启动Solr后就出现报错LOG,有人已经在OSCHINA中向IK项目提交BUG了,见此链接

废话不多,直接上修改方案吧!

我修改的IK代码版本为K-Analyzer-2012FF_hf1,如果你的是其他版本的,那么对照着修改或者直接下个这版本的改吧,IK GIT传送门

一共需要修改的是4个文件:均在org\wltea\analyzer这个目录下

1、首先是lucene文件夹下的IKAnalyzerIKTokenizer

首先改IKAnalyzer文件

Lucene5中createComponents的原型由Lucene4中的(String, Reader)变更为了(String)【关于Lucene的API变更,大家自己去apache官网的API站点查阅比较吧】,因此该部分代码修改为

/**
	 * 重载Analyzer接口,构造分词组件
	 * 调整支持Lucene 5.0 createComponents构造为(String),移除原有Reader in参数
	 */
	@Override
	//protected TokenStreamComponents createComponents(String fieldName, final Reader in) {
	protected TokenStreamComponents createComponents(String fieldName) {
		Tokenizer _IKTokenizer = new IKTokenizer(this.useSmart());
		return new TokenStreamComponents(_IKTokenizer);
	}

接下来是IKTokenizer文件

由于上面的createComponents移除了Reader in参数,因此IKTokenizer的构造也就不再需要这个参数和对应的处理了,移除掉参数和super就好了。

/**
	 * Lucene 4.0 Tokenizer适配器类构造函数 —— Lucene5.0 移除原有参数Reader in
	 * @param useSmart
	 */
	//public IKTokenizer(Reader in , boolean useSmart){
	public IKTokenizer(boolean useSmart){
		//屏蔽原有参数Reader in的处理,Lucene会调用setReader来处理此项内容
		//super(in);
	    offsetAtt = addAttribute(OffsetAttribute.class);
	    termAtt = addAttribute(CharTermAttribute.class);
	    typeAtt = addAttribute(TypeAttribute.class);
		_IKImplement = new IKSegmenter(input , useSmart);
	}


关于移除此参数的说明:官方文档说调用setRaeder来替代,我也不知道是自己调用还是lucene自己会调用,而且IK的代码我没全部看(我是.NET开发我会说NOTEPAD看JAVA累?其实是懒),也没看到IK里面这reader有咩作用,因此干脆移除掉,事后验证发现运行正常,也没什么不适应。

2、query下的SWMCQueryBuilder和sample下的LuceneIndexAndSearchDemo

Lucene5中移除了Version,因此很多API中的Version参数都被移除了,同样大家自行翻阅官方CHANGE说明。

首先是SWMCQueryBuilder文件,getSWMCQuery方法中调用的QueryParser和StandardAnalyzer均受上述原因影响,因此移除代码中的Version.LUCENE_40

//借助lucene queryparser 生成SWMC Query
		//调整支持Lucene5.0 QueryParser构造中移除了QueryParser(Version,String,Analyzer),直接使用QueryParser(String,Analyzer)
		//调整支持Lucene5.0 StandardAnalyzer构造中移除了QueryParser(Version),直接使用QueryParser()
		QueryParser qp = new QueryParser(fieldName, new StandardAnalyzer());
		qp.setDefaultOperator(QueryParser.AND_OPERATOR);
		qp.setAutoGeneratePhraseQueries(true);

然后是LuceneIndexAndSearchDemo文件,这个是案例,其实文件删除就好了的说

与上面一样,移除代码中的Version.LUCENE_40

String keyword = "中文分词工具包";			
			//使用QueryParser查询分析器构造Query对象
			//调整支持Lucene5.0 QueryParser构造中移除了QueryParser(Version,String,Analyzer),直接使用QueryParser(String,Analyzer)
			QueryParser qp = new QueryParser(fieldName,  analyzer);
			qp.setDefaultOperator(QueryParser.AND_OPERATOR);
			Query query = qp.parse(keyword);
			System.out.println("Query = " + query);

至此全部修改完成,编译打包就O了,记得编译时需要lucene5对应的jar包哦。

最后:

我就不po源码了,因为我的源码有过别的修改,1个是IKTokenizerFactory实现,另外1个是IK分词的BUG,不过貌似SOLR里面的所有分词均有此“BUG”,当文本包含HTML标记,且分词使用了charFilter移除HTML标记时,分词结果中的位置标记存在偏移,这会导致显示的时候高亮错位,因为我不是做的Lucene定制开发,是直接使用Solr(.NET开发捂脸啊...),当时为了这个BUG那是翻了无数个网页找原因找方案修复,不过也只修复了一半(在网上找到了1个方案googlecode中有人提交了此BUG并附上了自己的修复方案,我直接COPY来的),起始位置正确了,但结束位置还是偏移的。

需要JAR包和源码的可以移步益达那里去,他也改了这个,只不过他偷懒没写完整,但附上了代码,他没有移除Reader in参,这点就是我先前纠结的点,至于是不是真的不需要内容了,大家运行试试吧。益达的传送门!注意,益达把源码放在了pan里,该死的链接需要手工COPY。

标签: Lucene Solr IK Lucene5 Solr5
共有 人打赏支持
粉丝 4
博文 4
码字总数 1909
评论 (3)
MikyChow
博主你好,我使用您提供的ik分词器后在solr5.3上运行发现以下错误:
{"responseHeader":{"status":500,"QTime":1},"error":{"trace":"java.lang.NullPointerException\r\n\tat java.io.StringReader.<init>(Unknown Source)\r\n\tat org.wltea.analyzer.lucene.IKAnalyzer.createComponents(IKAnalyzer.java:74)\r\n\tat org.apache.lucene.analysis.Analyzer.tokenStream(Analyzer.java:179)\r\n\tat org.apache.solr.handler.AnalysisRequestHandlerBase.analyzeValue(AnalysisRequestHandlerBase.java:91)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.analyzeValues(FieldAnalysisRequestHandler.java:221)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.handleAnalysisRequest(FieldAnalysisRequestHandler.java:182)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.doAnalysis(FieldAnalysisRequestHandler.java:102)\r\n\tat org.apache.solr.handler.AnalysisRequestHandlerBase.handleRequestBody(AnalysisRequestHandlerBase.java:63)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:143)\r\n\ta
MikyChow
由于本人是做.net开发,所以还烦请博主帮助修正下
God_Seven

引用来自“MikyChow”的评论

博主你好,我使用您提供的ik分词器后在solr5.3上运行发现以下错误:
{"responseHeader":{"status":500,"QTime":1},"error":{"trace":"java.lang.NullPointerException\r\n\tat java.io.StringReader.<init>(Unknown Source)\r\n\tat org.wltea.analyzer.lucene.IKAnalyzer.createComponents(IKAnalyzer.java:74)\r\n\tat org.apache.lucene.analysis.Analyzer.tokenStream(Analyzer.java:179)\r\n\tat org.apache.solr.handler.AnalysisRequestHandlerBase.analyzeValue(AnalysisRequestHandlerBase.java:91)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.analyzeValues(FieldAnalysisRequestHandler.java:221)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.handleAnalysisRequest(FieldAnalysisRequestHandler.java:182)\r\n\tat org.apache.solr.handler.FieldAnalysisRequestHandler.doAnalysis(FieldAnalysisRequestHandler.java:102)\r\n\tat org.apache.solr.handler.AnalysisRequestHandlerBase.handleRequestBody(AnalysisRequestHandlerBase.java:63)\r\n\tat org.apache.solr.handler.RequestHandlerBase.handleRequest(RequestHandlerBase.java:143)\r\n\ta
你报错的堆栈显示是调用IKAnalyzer.java的createComponents方法出现了错误,而且是StringReader初始化的时候出现NullPointerException,你是不是还保留着Reader reader = new BufferedReader(new StringReader(fieldName));这行代码??我上面写的已经没有这行代码了,你可以注释/去掉这行
×
God_Seven
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: