您的位置:首页 > 其它

solr入门之拼音加汉字方式的搜索建议自动补全的不高效实现

2017-01-03 09:23 507 查看
转载自:http://blog.csdn.net/sqh201030412/article/details/51018294

今天思考实现了下字符加汉字的搜索建议的 实现--思想主要还是昨天的思想,不过这个方法使用的是匹配查询 ,查询速度可能不太理想

[java] view
plain copy

 





/** 

 *  

 * @描述:用于完成拼音加汉字  组合情况的搜索建议   ---尽量少用  

 * @param params 

 * @return 

 * @return ResultData<List<BaseSuggestIndex>> 

 * @exception 

 * @createTime:2016年3月30日 

 * @author: songqinghu 

 */  

@RequestMapping(value="/more.json")  

@ResponseBody      

public ResultData<List<BaseSuggestIndex>> moreAuto(SearchParams params){  

      

    ResultData<List<BaseSuggestIndex>> result = querySuggestServiceImpl.detailedSearch(params);  

      

    if(result ==null){  

        result =  new ResultData<List<BaseSuggestIndex>>();  

        result.setSuccess(false);  

    }  

    return result;  

}  

[java] view
plain copy

 





/** 

  * 进行匹配模式的查询---如果是拼音+汉字形式  转汉字为拼音 

  */  

 @Override  

 public ResultData<List<BaseSuggestIndex>> detailedSearch(SearchParams params) {  

       

     String q = params.getQ();  

       

     SolrQuery query = new  SolrQuery();  

       

     Formula f = new Formula();  

       

     if(q != null && q.trim().length()>0){  

           

         String[] matching = SearchMachinUtils.getMatching(q);  

         for (int i = 0; i < matching.length; i++) {  

               

              f.append(new Query(BaseSuggestIndex.Fd.suggest.name(), matching[i]));  

              f.append(f.tagB());  

              if(i != matching.length-1){  

                  f.append(f.tagO());  

                  f.append(f.tagB());  

              }  

         }  

     }  

  

   //设置显示的 字段 --固定值 word  

   if(params.getFl() !=null && params.getFl().length()>0){  

       query.set(CommonParams.FL,params.getFl());  

   }  

   //过滤的类型--确定属性  

   if(params.getType() !=null && params.getType().trim().length()>0){  

       query.setFilterQueries(BaseSuggestIndex.Fd.type.name()+":"+params.getType());  

   }  

   String exe  = f.toString();  

   //主条件--如果传过来的是空   ---先暂时返回空  以后可能返回热词语  

   if(exe.isEmpty()){  

       ResultData<List<BaseSuggestIndex>> result = new ResultData<List<BaseSuggestIndex>>();  

       result.setData(null);  

       result.setTotalCount(0l);  

       result.setSuccess(false);  

       result.setMessage("查询条件为空");  

       return result;  

   }  

   query.set(CommonParams.Q,exe);  

   query.setStart(params.getStart());  

   query.setRows(params.getRows());  

   query.setSort(BaseSuggestIndex.Fd.count.name(), ORDER.desc);  

     

   //查询结果  

   try {  

       QueryResponse response = solrClient.query(query);  

       long numFound = response.getResults().getNumFound();  

       List<BaseSuggestIndex> words = response.getBeans(BaseSuggestIndex.class);  

       logger.info("Date={},formula={},NumFound={}",new Date(), exe,numFound);  

         

       ResultData<List<BaseSuggestIndex>> result = new ResultData<List<BaseSuggestIndex>>();  

       result.setData(words);  

       result.setTotalCount(numFound);  

       result.setSuccess(true);  

       return result;  

   } catch (Exception e) {  

       logger.error(" q={} in job solr query fail.", query.getQuery(), e);  

       return null;  

   }  

 }  

转换工具类

[java] view
plain copy

 





package cn.com.mx.gome.search.core.util;  

  

import java.util.ArrayList;  

import java.util.Hashtable;  

import java.util.List;  

import java.util.Map;  

import java.util.Set;  

  

import org.slf4j.Logger;  

import org.slf4j.LoggerFactory;  

  

import net.sourceforge.pinyin4j.PinyinHelper;  

import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;  

import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;  

import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;  

import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;  

  

/** 

 * 对查询主条件进行处理 

 * 形式  数字  拼音  汉字  进行模糊匹配查询  

 * @author songqinghu 

 * 

 */  

public class SearchMachinUtils {  

  

    private  static Logger logger = LoggerFactory.getLogger(Pinyin4jUtil.class);  

      

    /** 

     *  

     * @描述:对查询条件进行处理 获取匹配条件 

     * @param condition 

     * @return 

     * @return String[] 

     * @exception 

     * @createTime:2016年3月30日 

     * @author: songqinghu 

     */  

    private static StringBuffer getpinyin(String condition){  

          

        //设置字符容器类  

        StringBuffer pinyinName = new StringBuffer();  

        char[] chars = condition.toCharArray();  

        //设置拼音转换器  

        HanyuPinyinOutputFormat defaultFormat = new  HanyuPinyinOutputFormat();  

        defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);  

        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);  

        //判断转换拼凑----关键在这里  

        for (char c : chars) {  

            if(c>128){  

                try {  

                    String[] strs = PinyinHelper.toHanyuPinyinStringArray(c, defaultFormat);  

                    if(strs !=null){  

                        for (int i = 0; i < strs.length; i++) {  

                            pinyinName.append(strs[i]+"*");// 测试  ceshi*---  

                            if( i != strs.length -1){  

                                pinyinName.append(",");  

                            }  

                        }  

                    }  

                } catch (BadHanyuPinyinOutputFormatCombination e) {  

                    logger.error("",e);  

                }  

            }else if( c >=48 && c<=57  ){//0-9---查询匹配  

                pinyinName.append(c+"*");   

            }else if( c >=65 && c<=90){//A-Z  

                pinyinName.append(c+"*");  

            }else if( c >=97 && c<=122){//a-z  

                pinyinName.append(c+"*");  

            }  

            pinyinName.append(" ");   

        }  

        return pinyinName;  

    }  

      

    /** 

     * 去除多音字重复数据 

     *  

     * @param theStr 

     * @return 

     */   

    private static List<Map<String, Integer>> discountTheChinese(String theStr) {   

        // 去除重复拼音后的拼音列表   

        List<Map<String, Integer>> mapList = new ArrayList<Map<String, Integer>>();   

        // 用于处理每个字的多音字,去掉重复   

        Map<String, Integer> onlyOne = null;   

        String[] firsts = theStr.split(" ");   

        // 读出每个汉字的拼音   

        for (String str : firsts) {   

            onlyOne = new Hashtable<String, Integer>();   

            String[] china = str.split(",");   

            // 多音字处理   

            for (String s : china) {   

                Integer count = onlyOne.get(s);   

                if (count == null) {   

                    onlyOne.put(s, new Integer(1));   

                } else {   

                    onlyOne.remove(s);   

                    count++;   

                    onlyOne.put(s, count);   

                }   

            }   

            mapList.add(onlyOne);   

        }   

        return mapList;   

    }   

      

    /** 

     * 解析并组合拼音,对象合并方案(推荐使用)---返回set<String> 

     *  

     * @return 

     */   

    private static  String[]  parseTheChinese(   

            List<Map<String, Integer>> list) {   

        Map<String, Integer> first = MinparseTheChineseByObject(list);  

        String [] result = null;  

        if (first != null && first.keySet().size()>0) {   

            // 遍历取出组合字符串   

            Set<String> set = first.keySet();  

            result = new String[set.size()];  

            int i = 0;  

            for (String string : set) {  

                result[i] = string;  

                i++;  

            }  

        }   

        return result;   

    }   

      

      

    /** 

     *  

     * @描述:方法抽取 

     * @param list 

     * @return 

     * @return Map<String,Integer> 

     * @exception 

     * @createTime:2016年3月22日 

     * @author: songqinghu 

     */  

     private static Map<String,Integer> MinparseTheChineseByObject(  

             List<Map<String, Integer>> list){  

         Map<String, Integer> first = null; // 用于统计每一次,集合组合数据   

         // 遍历每一组集合   

         for (int i = 0; i < list.size(); i++) {   

             // 每一组集合与上一次组合的Map   

             Map<String, Integer> temp = new Hashtable<String, Integer>();   

             // 第一次循环,first为空   

             if (first != null) {   

                 // 取出上次组合与此次集合的字符,并保存   

                 for (String s : first.keySet()) {   

                     for (String s1 : list.get(i).keySet()) {   

                         String str = s + s1;   

                         temp.put(str, 1);   

                     }   

                 }   

                 // 清理上一次组合数据   

                 if (temp != null && temp.size() > 0) {   

                     first.clear();   

                 }   

             } else {   

                 for (String s : list.get(i).keySet()) {   

                     String str = s;   

                     temp.put(str, 1);   

                 }   

             }   

             // 保存组合数据以便下次循环使用   

             if (temp != null && temp.size() > 0) {   

                 first = temp;   

             }   

         }   

         return first;  

     }  

       

      

    public static String[] getMatching(String condition){  

          

        return parseTheChinese(discountTheChinese(getpinyin(condition).toString()));   

    }  

      

      

}  

上一张查询的图片:



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  solr 搜索
相关文章推荐