升级Solr5.1的过程就不描述了,从4.10.2升上来,基本没有任何其他问题。但启动Solr后就出现报错LOG,有人已经在OSCHINA中向IK项目提交BUG了,见此链接。
废话不多,直接上修改方案吧!
我修改的IK代码版本为K-Analyzer-2012FF_hf1,如果你的是其他版本的,那么对照着修改或者直接下个这版本的改吧,IK GIT传送门
一共需要修改的是4个文件:均在org\wltea\analyzer这个目录下
1、首先是lucene文件夹下的IKAnalyzer和IKTokenizer
首先改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。