Solr学习总结 IK 配置中文分词器

  默认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);
  }
}
扫描二维码关注公众号,回复: 4650345 查看本文章

强制性的把依赖 换成自己需要的版本

剔除 

<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 插入数据即可实现中文分词  通过某些中文关键字搜索

猜你喜欢

转载自blog.csdn.net/weixin_43788708/article/details/84843323