solr入门之拼音加汉字方式的搜索建议自动补全的不高效实现
2016-03-30 19:08
645 查看
今天思考实现了下字符加汉字的搜索建议的 实现--思想主要还是昨天的思想,不过这个方法使用的是匹配查询 ,查询速度可能不太理想
转换工具类
上一张查询的图片:
/** * * @描述:用于完成拼音加汉字 组合情况的搜索建议 ---尽量少用 * @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; }
/** * 进行匹配模式的查询---如果是拼音+汉字形式 转汉字为拼音 */ @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; } }
转换工具类
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())); } }
上一张查询的图片:
相关文章推荐
- IOS学习之——位图上下文 -- 水印图片
- 关于UIView中的坐标转换
- IAR生成文件链接过程解析
- 模板实现动态顺序表
- Java虚拟机学习 - 内存调优
- Mac10.11 Xcode7 模拟器应用沙盒查看(手动)
- Adb connection Error:远程主机强迫关闭了一个现有的连接。
- 回调函数
- IOS学习之—— 定时器 NSTimer 和 CADisplayLink 类的使用
- opencv拼接相关1
- poj 1114 完全背包 dp
- 三角00
- HDFS原理分析(u)
- POJ2677,HDU2224【双调欧几里得模板题】
- Leetcode 169 Majority Element
- 面向对象 理论 笔试
- bzoj 3629 [JLOI2014]聪明的燕姿(约数和,搜索)
- 三角形问题该改改
- HZNU-1480-The Gougu Theorem【勾股数】
- hdu 4540 威威猫系列故事——打地鼠【暴力dp】