Solr进阶之拼写纠错功能的实现基础拼音

思路:
1.当汉字个数小于等于三个汉字时,使用单个词库进行匹配(最大匹配法)
将汉字转为同音字,查询单个词库中的数据,选出音一样的词语列表,加上最小距离算法(保证至少一个汉字一样),得出一个列表,按照一定的算法排序后,选出最好的那个词语.
(词语库中词语定时更新,索引对应词语的查询结果)
2.当汉字个数在4到6个数目时,使用最大匹配切词法进行切词处理,切分为单个最大词后,使用1中的排序法则,排序后,(这里词语的组合如何去做?? 先不做,涉及nlp),直接得到最佳的三个词语吧,进行查询,得到结果数.再次使用最小距离算法的方式(solr自身的)进行一次纠错,将两次纠错结果进行算法排序,得出最优化结果
3.当查询汉字个数大于6个时,使用切词的方式进行处理,将词库中需要查询到的汉字预先使用n-gram处理后,将汉字和拼音为一个单位放入多值字段中.
将查询的汉字使用n-gram切分后,转为拼音,进行上述字段的查询,对每个拼音对应的进行高亮处理,取出对应的列表,将一系列汉字组合后,假设经过优化后(最小距离,前后关系 等)数目是3,将这个三个词语再次查询,查出相应的结果数目,
再次使用solr自身的最小距离算法模块,查出一个纠错列表
将两次结果经过算法处理后,得出最优解,给出建议!


准备工作:
1.建立一个词库(这里简单的使用商品相关信息加分词器完成)
2.在商品库中添加一个字段单元 形式 如下  洗 xi ,衣 yi ,机 ji ...


代码实现:

将思路中的1.2合并了下.原理都是一样的.

 @Override
    public ResultData<String> productSpellCheck(SearchParams params) {
        String spellWrod =null;
        //判断查询词的长度根据不同长度使用不同的处理方式
        int length = params.getQ().length();

        if(length>1 && length<7){//最大匹配分词法
            spellWrod = this.maxMatching(params.getQ());
            if(spellWrod==null || spellWrod.length()==0){
                spellWrod = this.minSpilt(params.getQ());
            }
        }else if(length>6 && length <=10){//最小切割法
            spellWrod=this.minSpilt(params.getQ());
        }

        ResultData<String> resultData = new ResultData<String>();
        resultData.setData(spellWrod);
        if(spellWrod !=null && spellWrod.length()>0){
            resultData.setSuccess(true);
        }else{
            resultData.setSuccess(false);
        }
        return resultData;
    }

短词纠错部分实现  
    /**
     * @描述:最大匹配法 ---拼音加最小距离算法  
     * 电视机  名师辅导 权威名师辅导
     * @param word
     * @return String
     * @createTime:2016年9月12日
     * @author: songqinghu
     */
    private String maxMatching(String word){

        Map<String, String> oldWord = NGramTokenizerUtil.analyzer(word);
        String spellword="";

        List<SpellWordTree> spellWords = new ArrayList<SpellWordTree>();
        matching(oldWord,  word.length(), spellWords);
        if(spellWords.size()>0){
            int start = spellWords.get(spellWords.size()-1).getStart();
            if(start!=0){
                SpellWordTree spellWordTree = new SpellWordTree();
                spellWordTree.setKey(0+"-"+start);
                ArrayList<String> wordList = new ArrayList<String>();
                wordList.add(oldWord.get(spellWordTree.getKey()));
                spellWordTree.setWord(wordList);
                spellWords.add(spellWordTree);

            }
            List<String> words = new ArrayList<String>();
            words.add(spellword);//种子
            for (int i = spellWords.size()-1; i >=0; i--) {
                //spellword=spellword + spellWords.get(i).getWord();
                List<String> temp = new ArrayList<String>();
                for (String minword : spellWords.get(i).getWord()) {
                     for (String seedword : words) {
                            seedword = seedword + minword;
                            temp.add(seedword);
                        }
                }
                words = temp;
            }
            if(words.size()=
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值