Ik分词器和Ansj分词器

Ik和Ansj分词器

背景

开发某项目,使用到websocket以及IK分词器,用户输入信息,根据用户输入的信息,进行拆分词,匹配数据库的关键词,符合关键词规则的返回数据。

分词器

  • IK分词器
  • Ansj分词器

IK分词器

开源地址

IK分词器开源地址

引入jar包
<dependency>
		<groupId>com.github.magese</groupId>
		<artifactId>ik-analyzer</artifactId>
		<version>8.3.1</version>
	</dependency>
代码实践
/**
     * ik分词器
     *
     * @param custKeyword 输入词
     * @return 关键词数组
     */
    public String[] ikSolr(CustKeyword custKeyword) throws IOException {
        String key = "";
        Lexeme lexeme = null;
        StringReader stringReader = new StringReader(custKeyword.getKeyword());
        //第二个参数true;代表最大颗粒切分。false代表最细颗粒切分;
        IKSegmenter ikSegmenter = new IKSegmenter(stringReader, false);
        while ((lexeme = ikSegmenter.next()) != null) {
            key += lexeme.getLexemeText() + ",";
        }
        key = key.substring(0, key.length() - 1);
        String[] keywords = key.trim().split(",");
        return keywords;
    }
使用热更新自定义词词典进行分词

有时候我们对IK分词器系统默认词典并不满意,无法满足我们的实际项目需求。需要进行加入自定义词典才能满足需求。
例如,蚂蚁集团,IK分词器会拆分成“蚂蚁”和“集团”两组词语。如果不想拆开,就使用到了自定义词典了。用户配置的自定义词典内有“蚂蚁集团”,则IK分词器不会将这四个字拆开了。

网上的IK分词器大部分都是操作配置文件,不能满足我的实际需求。配置文件的缺点在于,一旦项目启动,配置文件中的自定义词也就确定了,后期就算新增了分词,新词也不会起作用。只能重启项目。

在项目中,我的需求是,需要加载数据库中配置的分词,IK分词器每次都要根据数据库中的自定义词进行分词。

代码
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.lucene.analysis.Analyzer;
import org.wltea.analyzer.cfg.Configuration;
import org.wltea.analyzer.cfg.DefaultConfig;
import org.wltea.analyzer.core.IKSegmenter;
import org.wltea.analyzer.core.Lexeme;
import org.wltea.analyzer.dic.Dictionary;
import org.wltea.analyzer.lucene.IKAnalyzer;
/**
 * LuceneHelper
 * @author wwz
 * @create 2019-08-28
 *
 */
public class LuceneHelperUtils {

    static Analyzer analyzer = new IKAnalyzer();
    static Dictionary dictionary = null;


    public static void init(){
        Configuration cfg = DefaultConfig.getInstance();  //加载词库
        cfg.setUseSmart(false); //true 用智能分词 ,false细粒度可以根根据可扩展词切词
        Dictionary.initial(cfg);
        dictionary = Dictionary.getSingleton();
    }

    /**
     * 添加自定义词
     * @param words
     */
    public static void addCustomWords(Set<String>words){
        dictionary.addWords(words);

    }
    /**
     * 删除自定义词
     * @param words
     */
    public static void disableCustomWords(Set<String>words){
        dictionary.disableWords(words);

    }
    public static List<String> queryWords(String query) {
        List<String> list = new ArrayList<String>();
        try {
            StringReader input = new StringReader(query.trim());
            // true 用智能分词 ,false细粒度可以根根据可扩展词切词
            IKSegmenter ikSeg = new IKSegmenter(input, false);
            for (Lexeme lexeme = ikSeg.next(); lexeme != null; lexeme = ikSeg.next()){
                list.add(lexeme.getLexemeText());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }
    
    public static void main(String[] args) {
        init();
        System.out.println(queryWords("养老证"));
        Set<String> words = new HashSet<String>();
        words.add("养老证");
        addCustomWords(words);
        disableCustomWords(words);
        System.out.println(queryWords("养老证"));
    }
    
    /**
     * 加入自定义词典后的分词方法
     * @param keyword 输入词
     */
public String[] ikWords(String keyword) throws Exception {
    init();
    Set<String> words = new HashSet<String>();
    //查询数据库所有分词
    String allKeyWord = custKeyQuestionService.selectCustAllKeyword();
    if (StringUtils.isNotEmpty(allKeyWord)) {
        String[] keywordArr = allKeyWord.trim().split(",");
        for (int x = 0; x < keywordArr.length; x++) {
            words.add(keywordArr[x]);
        }
    }
    addCustomWords(words);//添加自定义词
    String key = "";
    Lexeme lexeme = null;
    StringReader stringReader = new StringReader(keyword.trim());
    //第二个参数true;代表最大颗粒切分。false代表最细颗粒切分;
    IKSegmenter ikSegmenter = new IKSegmenter(stringReader, false);
    while ((lexeme = ikSegmenter.next()) != null) {
        key += lexeme.getLexemeText() + ",";
    }
    key = key.substring(0, key.length() - 1);
    System.out.println("分词结果=======================" + key);
    String[] keywords = key.trim().split(",");
    return keywords;
}

Ansj分词器

开源地址

Ansj分词器开源地址

引入jar包
<dependency>
		<groupId>org.ansj</groupId>
		<artifactId>ansj_seg</artifactId>
		<version>5.1.6</version>
	</dependency>
代码实践
/**
     * Ansj分词器
     *
     * @param custKeyword 输入词
     * @return 关键词数组
     */
    public String[] ansjSolr(CustKeyword custKeyword) throws IOException {
        String contentKeyword = NlpAnalysis.parse(custKeyword.getKeyword()).toStringWithOutNature();
        String[] keywords = contentKeyword.trim().split(",");
        return keywords;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值