文档章节

Solr4.10和ANSJ 中文分词集成

go2school
 go2school
发布于 2014/11/07 17:15
字数 742
阅读 242
收藏 2
点赞 0
评论 0

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
粉丝 10
博文 34
码字总数 14674
作品 0
技术主管
Solr中文高亮位置偏移

我正在使用Solr4.10,配合Ansj来做中文分词。最近发现的问题是,Solr的高亮显示会出现偏移,比如有这样一个句子:具有常识性的计算机知识。如果搜索计算机应该返回: 具有常识性的计算机知识 ...

go2school
2015/08/25
187
0
基于 Ansj 的 elasticsearch 2.3.1 中文分词插件

前言 这是一个elasticsearch的中文分词插件,基于Ansj中文分词。发起者Onni大神。 2.3.1插件安装 进入Elasticsearch目录运行如下命令 进入es目录执行如下命令 ./bin/plugin install http://...

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

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

ansj
2014/05/13
5K
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
3.8K
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
Elasticsearch安装中文分词插件ik

直接下载集成版本,elasticsearch中文发行版,针对中文集成了相关插件,并带有Demo,方便新手学习,或者在生产环境中直接使用 https://github.com/medcl/elasticsearch-rtf 什么是ElasticSear...

凯文加内特
2015/09/16
199
0
中文分词工具

中文分词工具非常繁多,主要与大家分享其中几个工具,这是本人第一次接触中文分词工具,望轻喷。 中文分词工具: 1、IK Analyzer 是一个开源的,基于java语言开发的轻量级的中文分词工具包。...

阿阿阿阿阿局
2016/05/10
403
0
word分词器、ansj分词器、mmseg4j分词器、ik-analyzer分词器分词效果评估

word分词是一个Java实现的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。 能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录...

杨尚川
2014/04/29
0
1
阿杜杜不是阿木木/spring-boot-data-supporter

spring-boot-data-supporter 本项目的Mysql和MongoDB数据库(下面是详细的处理过程,免做伸手党,学习学习没坏处): https://git.oschina.net/duhongming/spring-boot-data-supporter/atta...

阿杜杜不是阿木木
2017/03/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kafka设计解析(一)- Kafka背景及架构介绍

原创文章,转载请务必将下面这段话置于文章开头处。(已授权InfoQ中文站发布) 本文转发自技术世界,原文链接 http://www.jasongj.com/2015/03/10/KafkaColumn1 摘要   Kafka是由LinkedI...

mskk
6分钟前
0
0
使用Service Mesh整合您的微服务架构

在微服务架构的世界中,它正在达到这样的程度,即管理系统的复杂性对于利用它带来的好处变得至关重要。 目前,如何实现这些微服务不再是一个问题,因为有很多可用的框架(Spring Boot,Vert....

xiaomin0322
9分钟前
0
0
看看 LinkedList Java 9

终于迎来了 LinkedList 类,实现的接口就有点多了 Serializable, Cloneable, Iterable<E>, Collection<E>, Deque<E>, List<E>, Queue<E>。LinkedList是一个实现了List接口和Deque接口的双端链......

woshixin
27分钟前
0
0
算法 - 冒泡排序 C++

大家好,我是ChungZH。今天我给大家讲一下最基础的排序算法:冒泡排序(BubbleSort)。 冒泡排序算法的原理如下: 比较相邻的元素。如果第一个比第二个大(可以相反),就交换他们两个。 对每...

ChungZH
30分钟前
0
0
jquery ajax request payload和fromData请求方式

请求头的不同 fromData var data = { name : 'yiifaa'};// 提交数据$.ajax('app/', { method:'POST', // 将数据编码为表单模式 contentType:'application/x-ww...

lsy999
32分钟前
0
0
阿里P7架构师,带你点亮程序员蜕变之路

前言: Java是现阶段中国互联网公司中,覆盖度最广的研发语言。 掌握了Java技术体系,不管在成熟的大公司,快速发展的公司,还是创业阶段的公司,都能有立足之地。 有不少朋友问,成为Java架...

Java大蜗牛
34分钟前
1
0
Ecstore 在没有后台管理界面(维护)的情况如何更新表的字段

window 系统: 切换到:app\base 目录下: C:\Users\qimh>d: D:\>cd D:\WWW\huaqh\app\base 执行:D:\WWW\huaqh\app\base>cmd update linux 系统: 1># cd /alidata/www.novoeshop.com/app/......

qimh
38分钟前
0
0
设计模式-策略模式

策略模式 解释 对工厂模式的再次封装,使用参数控制上下文信息(将工厂返回的实例赋值给context field) 不会返回bean实例,只是设置对应的条件 调用context的方法(调用field的方法) 用户只...

郭里奥
41分钟前
0
0
python使用有序字典

python自带的collections包中有很多有用的数据结构可供使用,其中有个叫OrderedDict类,它可以在使用的时候记录元素插入顺序,在遍历使用的时候就可以按照原顺序遍历。 a = {"a":1,"b"...

芝麻糖人
今天
0
0
RestTemplate HttpMessageConverter

RestTemplate 微信接口 text/plain HttpMessageConverter

微小宝
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部