文档章节

Solr4.10和ANSJ 中文分词集成

go2school
 go2school
发布于 2014/11/07 17:15
字数 742
阅读 248
收藏 2

1. 具体代码

 1.1 ANSJTokenizerFactory 工厂类

package org.ansj.solr;

import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.util.AttributeFactory;

import java.io.IOException;
import java.io.Reader;
import java.util.Map;


public class ANSJTokenizerFactory extends TokenizerFactory {

	private ThreadLocal<ANSJTokenizer> tokenizerLocal = new ThreadLocal<ANSJTokenizer>();
	 
	
  /** Creates a new ANSJTokenizerFactory */
  public ANSJTokenizerFactory(Map<String,String> args) {
    super(args);
    assureMatchVersion();
    if (!args.isEmpty()) {
      throw new IllegalArgumentException("Unknown parameters: " + args);
    }
  }

  @Override
  public ANSJTokenizer create(AttributeFactory factory, Reader input) {
	  
    ANSJTokenizer tokenizer = tokenizerLocal.get();     
    if(tokenizer == null) {
        tokenizer = newTokenizer(factory, input);       
    }
    try {
            tokenizer.setReader(input);
    } catch (IOException e) {
            tokenizer = newTokenizer(factory, input);
    }
 
    return tokenizer;
    
  }
  
  private ANSJTokenizer newTokenizer(AttributeFactory factory, Reader input) {
      ANSJTokenizer tokenizer = new ANSJTokenizer(factory, input);
      tokenizerLocal.set(tokenizer);
      return tokenizer;
}
}

1.2 ANSJTokenizer类

package org.ansj.solr;
 
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.Writer;

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.apache.lucene.util.AttributeFactory;

import org.ansj.domain.Term;
import org.ansj.splitWord.Analysis;
import org.ansj.splitWord.analysis.ToAnalysis;

public final class ANSJTokenizer extends Tokenizer {

	Analysis udf = null;

    private int offset = 0, bufferIndex=0, dataLen=0;
    private final static int MAX_WORD_LEN = 255;
    private final static int IO_BUFFER_SIZE = 1024;
    private final char[] buffer = new char[MAX_WORD_LEN];
    private final char[] ioBuffer = new char[IO_BUFFER_SIZE];

    private int length;
    private int start;

    private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
    private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
    private final TypeAttribute typeAtt = (TypeAttribute)addAttribute(TypeAttribute.class);
    
    public ANSJTokenizer(Reader in) {
        super(in);        
      }

      public ANSJTokenizer(AttributeFactory factory, Reader in) {
        super(factory, in);
      }
      
      public Analysis getAnalysis()
      {
    	  udf = new ToAnalysis(input);   
    	  return udf;
      }
      
    private final boolean flush() {

        if (length>0) {
            //System.out.println(new String(buffer, 0,
            //length));
          termAtt.copyBuffer(buffer, 0, length);
          offsetAtt.setOffset(correctOffset(start), correctOffset(start+length));
          return true;
        }
        else
            return false;
    }

    @Override
    public boolean incrementToken() throws IOException {
    	clearAttributes();
    	if(udf == null)
    	{
    		udf = getAnalysis();
    	}
    	
        Term term = udf.next();
         
        if(term != null) {
                termAtt.copyBuffer(term.getName().toCharArray(), 0, term.getName().length());
                               
                //if the text has newline, then the first word in the newly started line will have start position 1, which will 
                //cause the if condition failed, in original code, it can cause serious problem. 
                if(term.getTo().getOffe() < term.getOffe() || term.getTo().getOffe() < 0)
                {
                	offsetAtt.setOffset(term.getOffe(), term.getOffe() +term.getName().length());
                	typeAtt.setType("word");
                	return true;
                }
                //added by xiao for debugging
                
                else
                {
                	offsetAtt.setOffset(term.getOffe(), term.getTo().getOffe());
                	typeAtt.setType("word");
                	return true;
                }                
        } else {
                end();
                return false;
        }
    }
    
    @Override
    public final void end() throws IOException {
      super.end();
      // set final offset
      final int finalOffset = correctOffset(offset);
      this.offsetAtt.setOffset(finalOffset, finalOffset);
    }

    @Override
    public void reset() throws IOException {
      super.reset();
      offset = bufferIndex = dataLen = 0;     
      udf = new ToAnalysis(input);      
    }
    
    @Override
    public void close() throws IOException {
      super.close();
      offset = bufferIndex = dataLen = 0;
      
    }
    
}

2. 打包ansj工程,将导出的jar包添加到solr.war中的WEB-INF\lib\目录,同样将ansj依赖的nlp-lang.jar包添加,不然会报错。 

3. 将ansj下的resources目录拷贝到solr的example目录,不然运行solr时会说找不到词性文件。有其他配置方法,但我没想到。 

4. 修改solr自带例子的schema.xml文件,添加如下两行

<field name="chinese_ansj_text" type="text_cn" indexed="true" stored="true" />
<fieldType name="text_cn" class="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
<tokenizer class="org.ansj.solr.ANSJTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
         <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
<tokenizer class="org.ansj.solr.ANSJTokenizerFactory"/>
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>

修改solr的exampledocs中的gb18030-example,增加一行

<add>
  <doc>
    <field name="id">GB18030TEST</field>
    <field name="name">Test with some GB18030 encoded characters</field>
    <field name="features">No accents here</field>
    <field name="features">这是一个功能</field>
    <field name="features">This is a feature (translated)</field>
    <field name="features">这份文件是很有光泽</field>
    <field name="features">This document is very shiny (translated)</field>
    <field name="price">0</field>
    <field name="inStock">true</field>
<field name="chinese_ansj_text">这份文件是很有光泽</field>
  </doc>
</add>

5.做实验,在solr的analysis页面中输入“数据挖掘一般是指从大量的数据中通过算法搜索隐藏于其中信息的过程”,点击analyze,显示

在Solr管理端的Query输入chinese_ansj_text:光泽,点击查询,显示结果












© 著作权归作者所有

共有 人打赏支持
go2school
粉丝 11
博文 34
码字总数 14674
作品 0
技术主管
私信 提问
基于 Ansj 的 elasticsearch 2.3.1 中文分词插件

前言 这是一个elasticsearch的中文分词插件,基于Ansj中文分词。发起者Onni大神。 2.3.1插件安装 进入Elasticsearch目录运行如下命令 更新内容 elasticsearch更新2.3.1 ansj_seg升级至3.7.3...

ansj
2016/04/25
4.3K
9
Ansj 中文分词 1.41 发布

ansj中文分词是一个完全开源的,基于google语义模型+条件随机场模型的中文分词的java实现.具有使用简单开箱即用等特点。分词速度达到每秒钟大约100万字左右(mac air下测试),准确率能达到9...

ansj
2014/05/13
5.2K
4
中文分词--Ansj

Ansj中文分词 这是一个ictclas的java实现.基本上重写了所有的数据结构和算法.词典是用的开源版的ictclas所提供的.并且进行了部分的人工优化 内存中中文分词每秒钟大约100万字(速度上已经超越...

ansj
2012/09/06
31K
2
ansj 中文分词 5.0.1 发布

ansj中文分词是一个完全开源的,基于google语义模型+条件随机场模型的中文分词的java实现.具有使用简单开箱即用等特点。分词速度达到每秒钟大约100万字左右(mac air下测试),准确率能达到9...

ansj
2016/07/30
4K
1
Java实现中文word2vec

依赖: java深度学习框架,deeplearning4j:http://deeplearning4j.org/word2vec 开源中文分词框架,ansjseg:http://www.oschina.net/p/ansj 项目GitHub地址:https://github.com/YuyuZha0/wor......

Acce1erator
2016/04/21
2.2K
6

没有更多内容

加载失败,请刷新页面

加载更多

Windows / Linux / MacOS 设置代理上网的方法汇总

本文汇总了 Windows / Linux / MacOS 设置代理上网的各种方法,总结如下: 1、设置系统代理(Windows、Linux、MacOS) 2、设置代理插件(Chrome、Chromium、Firefox、Opera、QQ等浏览器) 3、...

sunboy2050
昨天
1
0
自定义 Maven 的 repositories

有时,应用中需要一些比较新的依赖,而这些依赖并没有正式发布,还是处于milestone或者是snapshot阶段,并不能从中央仓库或者镜像站上下载到。此时,就需要 自定义Maven的<repositories>。 ...

waylau
昨天
1
0
徒手写一个es6代码库

mkdir democd demonpm initnpm install -g babelnpm install -g babel-clinpm install --save-dev babel-preset-es2015-node5 在项目目录创建两个文件夹 functional-playground ......

lilugirl
昨天
2
0
linux定位应用问题的一些常用命令,特别针对内存和线程分析的dump命令

1.jps找出进程号,找到对应的进程号后面才好继续操作 2.linux查看进程详细信息 ps -ef | grep 进程ID 3. dump内存信息 Jmap -dump:format=b,file=YYMMddhhmm.dump pid 4.top查看cpu占用信息 ...

noob_chr
昨天
2
0
Android TV开发-按键焦点

写在前面 按键焦点过程了解 2.1 dispatchKeyEvent 过程了解 2.2 焦点查找请求过程了解 1.2.1 第一次获取焦点 1.2.3 按键焦点 焦点控制 焦点记忆 应用场景 参考资料 [TOC] 1. 写在前面 工...

冰雪情缘l
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部