Authored by Gino Zhang

搜索提示词增加拼写检查

@@ -209,25 +209,29 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl @@ -209,25 +209,29 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl
209 suggestSearchParam.setSize(0); 209 suggestSearchParam.setSize(0);
210 suggestSearchParam.setSuggestionBuilder(SuggestBuilders.termSuggestion("keyword_suggestion").text(keyword).field("keyword").size(1)); 210 suggestSearchParam.setSuggestionBuilder(SuggestBuilders.termSuggestion("keyword_suggestion").text(keyword).field("keyword").size(1));
211 SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_SUGGEST, suggestSearchParam); 211 SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_SUGGEST, suggestSearchParam);
212 - if (searchResult != null && searchResult.getSuggestionMap() != null && searchResult.getSuggestionMap().get("keyword_suggestion") != null) {  
213 - TermSuggestion suggestion = (TermSuggestion) searchResult.getSuggestionMap().get("keyword_suggestion");  
214 - List<TermSuggestion.Entry> entries = suggestion.getEntries();  
215 - if (CollectionUtils.isNotEmpty(entries)) {  
216 - List<TermSuggestion.Entry.Option> entryList = entries.get(0).getOptions();  
217 - if (CollectionUtils.isNotEmpty(entryList)) {  
218 - TermSuggestion.Entry.Option option = entryList.get(0);  
219 - return option.getText().string();  
220 - }  
221 - }  
222 - }  
223 -  
224 - return null; 212 + return getCorrectKeywordFromResult(searchResult);
225 } catch (Exception e) { 213 } catch (Exception e) {
226 logger.error("Get suggestion by keyword [" + keyword + "] failed!", e); 214 logger.error("Get suggestion by keyword [" + keyword + "] failed!", e);
227 return null; 215 return null;
228 } 216 }
229 } 217 }
230 218
  219 + private String getCorrectKeywordFromResult(SearchResult searchResult) {
  220 + if (searchResult != null && searchResult.getSuggestionMap() != null && searchResult.getSuggestionMap().get("keyword_suggestion") != null) {
  221 + TermSuggestion suggestion = (TermSuggestion) searchResult.getSuggestionMap().get("keyword_suggestion");
  222 + List<TermSuggestion.Entry> entries = suggestion.getEntries();
  223 + if (CollectionUtils.isNotEmpty(entries)) {
  224 + List<TermSuggestion.Entry.Option> entryList = entries.get(0).getOptions();
  225 + if (CollectionUtils.isNotEmpty(entryList)) {
  226 + TermSuggestion.Entry.Option option = entryList.get(0);
  227 + return option.getText().string();
  228 + }
  229 + }
  230 + }
  231 +
  232 + return null;
  233 + }
  234 +
231 /** 235 /**
232 * 根据query词获取term建议和phrase建议。 236 * 根据query词获取term建议和phrase建议。
233 * 用于搜索结果数量太少或者无结果的时候给予用户的搜索建议。 237 * 用于搜索结果数量太少或者无结果的时候给予用户的搜索建议。
@@ -244,7 +248,7 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl @@ -244,7 +248,7 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl
244 248
245 try { 249 try {
246 // 2) 先调用suggest获取搜索提示词 只要能匹配到20%的term即可 250 // 2) 先调用suggest获取搜索提示词 只要能匹配到20%的term即可
247 - JSONObject suggestTipResult = suggestTipsBySuggestIndex(paramMap); 251 + JSONObject suggestTipResult = suggestTipsBySuggestIndex(paramMap, false);
248 if (suggestTipResult == null) { 252 if (suggestTipResult == null) {
249 // 2.1) 可能是ES发生异常 如果搜索不到相关是应该是集合为空而不是对象为null 253 // 2.1) 可能是ES发生异常 如果搜索不到相关是应该是集合为空而不是对象为null
250 return defaultSuggestTips(); 254 return defaultSuggestTips();
@@ -269,7 +273,7 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl @@ -269,7 +273,7 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl
269 } 273 }
270 } 274 }
271 275
272 - public JSONObject suggestTipsBySuggestIndex(Map<String, String> paramMap) { 276 + public JSONObject suggestTipsBySuggestIndex(Map<String, String> paramMap, boolean hasChangedKeyword) {
273 String queryWord = paramMap.get(SearchRequestParams.PARAM_SEARCH_KEYWORD); 277 String queryWord = paramMap.get(SearchRequestParams.PARAM_SEARCH_KEYWORD);
274 long begin = System.currentTimeMillis(); 278 long begin = System.currentTimeMillis();
275 logger.info("[func=suggestTipsBySuggestIndex][query={}][begin={}]", queryWord, begin); 279 logger.info("[func=suggestTipsBySuggestIndex][query={}][begin={}]", queryWord, begin);
@@ -317,7 +321,10 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl @@ -317,7 +321,10 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl
317 boolFilter.mustNot(QueryBuilders.termQuery("standardKeyword", CharUtils.standardized(queryWord))); 321 boolFilter.mustNot(QueryBuilders.termQuery("standardKeyword", CharUtils.standardized(queryWord)));
318 searchParam.setFiter(boolFilter); 322 searchParam.setFiter(boolFilter);
319 323
320 - // 2.4) 按照得分、权重、数量的规则降序排序 324 + // 2.4) 增加拼写纠错 为了增加缓存命中率 此次都增加拼写检查处理
  325 + searchParam.setSuggestionBuilder(SuggestBuilders.termSuggestion("keyword_suggestion").text(queryWord).field("keyword").size(1));
  326 +
  327 + // 2.5) 按照得分、权重、数量的规则降序排序
321 List<SortBuilder> sortBuilders = new ArrayList<>(3); 328 List<SortBuilder> sortBuilders = new ArrayList<>(3);
322 sortBuilders.add(SortBuilders.fieldSort("_score").order(SortOrder.DESC)); 329 sortBuilders.add(SortBuilders.fieldSort("_score").order(SortOrder.DESC));
323 sortBuilders.add(SortBuilders.fieldSort("weight").order(SortOrder.DESC)); 330 sortBuilders.add(SortBuilders.fieldSort("weight").order(SortOrder.DESC));
@@ -340,11 +347,22 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl @@ -340,11 +347,22 @@ public class SuggestServiceImpl implements ISuggestService, ApplicationEventPubl
340 347
341 // 5) 加入缓存 348 // 5) 加入缓存
342 suggestResult = new JSONObject(); 349 suggestResult = new JSONObject();
  350 + String correnctSpellingKeyword = getCorrectKeywordFromResult(searchResult);
343 List<String> resultTerms = searchResult.getResultList().stream().map(map -> (String) map.get("keyword")).collect(Collectors.toList()); 351 List<String> resultTerms = searchResult.getResultList().stream().map(map -> (String) map.get("keyword")).collect(Collectors.toList());
344 - suggestResult.put("terms_suggestion", resultTerms);  
345 - searchCacheService.addJSONObjectToCache(indexName, searchParam, suggestResult);  
346 - logger.info("[func=suggestTipsBySuggestIndex][query={}][cost={}]", queryWord, System.currentTimeMillis() - begin);  
347 - return suggestResult; 352 + if (CollectionUtils.isNotEmpty(resultTerms) || StringUtils.isEmpty(correnctSpellingKeyword) || hasChangedKeyword) {
  353 + suggestResult.put("terms_suggestion", resultTerms);
  354 + searchCacheService.addJSONObjectToCache(indexName, searchParam, suggestResult);
  355 + logger.info("[func=suggestTipsBySuggestIndex][query={}][cost={}]", queryWord, System.currentTimeMillis() - begin);
  356 + return suggestResult;
  357 + }
  358 +
  359 +
  360 + // 6) 执行拼写纠错处理 为了避免无限次递归 只允许拼写检查一次
  361 + logger.info("[func=suggestTipsBySuggestIndex]Switch the suggest keyword from [{}] to [{}].", queryWord, correnctSpellingKeyword);
  362 + Map<String, String> newParamMap = new HashMap<>(paramMap.size());
  363 + newParamMap.putAll(paramMap);
  364 + newParamMap.put(SearchRequestParams.PARAM_SEARCH_KEYWORD, correnctSpellingKeyword);
  365 + return suggestTipsBySuggestIndex(paramMap, true);
348 } 366 }
349 367
350 private JSONObject suggestTipsByConversionIndex(Map<String, String> paramMap) { 368 private JSONObject suggestTipsByConversionIndex(Map<String, String> paramMap) {