文档章节

Solr4.10和ANSJ 中文分词集成

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

没有更多内容

加载失败,请刷新页面

加载更多

Kali Linux Docker 練習

docker pull kalilinux/kali-linux-docker docker run -t -i kalilinux/kali-linux-docker /bin/bash apt-get update apt-get install htop apt-get install nmap apt-get install wpscan ap......

BaiyuanLab
今天
1
0
通俗大白话来理解TCP协议的三次握手和四次分手

最近在恶补计算机网络方面的知识,之前对于TCP的三次握手和四次分手也是模模糊糊,对于其中的细节更是浑然不知,最近看了很多这方面的知识,也在系统的学习计算机网络,加深自己的CS功底,就...

onedotdot
今天
2
0
TiDB 在爱奇艺的应用及实践

爱奇艺,中国高品质视频娱乐服务提供者,2010 年 4 月 22 日正式上线,推崇品质、青春、时尚的品牌内涵如今已深入人心,网罗了全球广大的年轻用户群体,积极推动产品、技术、内容、营销等全方...

TiDB
今天
1
0
Web系统大规模并发:电商秒杀与抢购

一、大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常...

xtof
今天
3
0
代码质量管理平台-sonarqube

在工作中,往往开发的时候会不怎么注重代码质量的人很多,存在着很多的漏洞和隐患等问题,sonarqube可以进行代码质量的审核,而且十分的残酷。。。。。接下来我们说下怎么安装 进入官网下载:...

落叶清风
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部