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