文档章节

Solr4.10和ANSJ 中文分词集成

go2school
 go2school
发布于 2014/11/07 17:15
字数 742
阅读 251
收藏 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

没有更多内容

加载失败,请刷新页面

加载更多

Jenkins基础入门-5-用户和权限管理

本篇,我们来介绍下Jenkins上如何创建用户,以及如何管理用户,和那些用户可以有ProjectA的权限。这个很好理解,一个项目,有开发和测试,和运维,每个团队都有不同的角色,例如有测试经理和...

shzwork
1分钟前
0
0
linux上解压版安装jdk,tomcat

需要的安装包 1.vmware12 2.centos7版本 3.安装完成后需要xshell来连接远程虚拟机,虚拟机保证要联网,网络畅通。 4.xftp用来向linux传输文件用,一般来说xshell和xftp配套使用 5.对应的压缩...

architect刘源源
37分钟前
23
0
使用 spring 的 IOC 解决程序耦合

工厂模式解耦 在实际开发中我们可以把三层的对象都使用配置文件配置起来,当启动服务器应用加载的时候,让一个类中的方法通过读取配置文件,把这些对象创建出来并存起来。在接下来的使用的时...

骚年锦时
今天
2
0
group by分组后获得每组中时间最大的那条记录

用途: GROUP BY 语句用于 对一个或多个列对结果集进行分组。 例子: 原表: 现在,我们希望根据USER_ID 字段进行分组,那么,可使用 GROUP BY 语句。 我们使用下列 SQL 语句: SELECT ID,US...

豆花饭烧土豆
今天
3
0
android6.0源码分析之Camera API2.0下的Preview(预览)流程分析

本文将基于android6.0的源码,对Camera API2.0下Camera的preview的流程进行分析。在文章android6.0源码分析之Camera API2.0下的初始化流程分析中,已经对Camera2内置应用的Open即初始化流程进...

天王盖地虎626
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部