Solr學習總結 IK 配置中文分詞器
阿新 • • 發佈:2018-12-26
預設solr沒有使用中文分詞器 所有搜尋的詞都是整個句子是一個詞 需要配置中文分詞器目前比較好用的是IK 但2012就停更了 只支援到Lucene4.7所有solr5.5需要Lucene5支援需要修改部分原始碼來支援solr5.5找到IKAnalyze類
<dependency> <groupId>com.janeluo</groupId> <artifactId>ikanalyzer</artifactId> <version>2012_u6</version> </dependency>
因為IK分詞器底層本來就是用lucene一些技術來實現的所以會給一些相關聯的包給下載下來但Lucene4.7.2跟solr5版本差異非常大所以需要改寫其中的一些類然後再重新打包
首先 先找到 IKAnalyzer這個類因為需要修改它的原始碼所以要去模仿它(包名類名內容需一致) 由於java遵守就近原則 它就不會去載入jar包裡的內容了會以當前類為主 本身的Ik是支援4.7.2的所以當前這個類也是能編譯通過的
程式碼修改對應的方法即可
IKAnalyzer
/** * */ package org.wltea.analyzer.lucene; import java.io.Reader; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.Tokenizer; /** */ public final class IKAnalyzer extends Analyzer { private boolean useSmart; public boolean useSmart() { return useSmart; } public void setUseSmart(boolean useSmart) { this.useSmart = useSmart; } /** */ public IKAnalyzer() { this(false); } /** */ public IKAnalyzer(boolean useSmart) { super(); this.useSmart = useSmart; } /**這裡就去掉了 Reader的一個引數 */ @Override protected TokenStreamComponents createComponents(String fieldName) { Tokenizer _IKTokenizer = new IKTokenizer(this.useSmart()); return new TokenStreamComponents(_IKTokenizer); } }
IKTokenizer
/** * */ package org.wltea.analyzer.lucene; import java.io.IOException; import java.io.Reader; import org.apache.lucene.analysis.Tokenizer; import org.apache.lucene.analysis.tokenattributes.CharTermAttribute; import org.apache.lucene.analysis.tokenattributes.OffsetAttribute; import org.apache.lucene.analysis.tokenattributes.TypeAttribute; import org.wltea.analyzer.core.IKSegmenter; import org.wltea.analyzer.core.Lexeme; public final class IKTokenizer extends Tokenizer { private IKSegmenter _IKImplement; private final CharTermAttribute termAtt; private final OffsetAttribute offsetAtt; private final TypeAttribute typeAtt; private int endPosition; //去掉了其中Reader的第一個構造引數 public IKTokenizer(boolean useSmart) { super();//去掉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) { termAtt.append(nextLexeme.getLexemeText()); termAtt.setLength(nextLexeme.getLength()); offsetAtt.setOffset(nextLexeme.getBeginPosition(), nextLexeme.getEndPosition()); endPosition = nextLexeme.getEndPosition(); typeAtt.setType(nextLexeme.getLexemeTypeString()); return true; } return false; } /* * (non-Javadoc) * @see org.apache.lucene.analysis.Tokenizer#reset(java.io.Reader) */ @Override public void reset() throws IOException { super.reset(); _IKImplement.reset(input); } @Override public final void end() { // set final offset int finalOffset = correctOffset(this.endPosition); offsetAtt.setOffset(finalOffset, finalOffset); } }
強制性的把依賴 換成自己需要的版本
剔除
<dependencies>
<!-- https://mvnrepository.com/artifact/com.janeluo/ikanalyzer -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
<!-- 剔除 -->
<exclusions>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 替換成自己需要的版本 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>5.5.5</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
<version>5.5.5</version>
</dependency>
</dependencies>
這時候4.7.2就替換成5.5.5了
在資料夾中找到 ikanalyzer-2012_u6.jar
雖然修改了java專案但包裡面的內容並沒有修改所以需要把編譯好的class檔案替換原始jar 替換完成後就支援5.5版本了
將solrhome下 配置檔案managed-schema 新增一個欄位型別 使用ik分詞器
<fieldType name="text_ik" class="solr.TextField" >
<analyzer type="index" isMaxWordLength="false" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
<analyzer type="query" isMaxWordLength="true" class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
不能修改 StrField 不支援自定義分詞器
<fieldType name="string" class="solr.StrField" sortMissingLast="true" >
</fieldType>
然後將對應需要進行中文分詞的欄位使用 text_ik該欄位型別 比如
<dynamicField name="*_s" type="text_ik" indexed="true" stored="true" />
重啟 或者 cloud環境下重新生成collection 插入資料即可實現中文分詞 通過某些中文關鍵字搜尋