Authored by Gino Zhang

优化重构搜索推荐词

... ... @@ -91,6 +91,7 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
Assert.isTrue(searchResult != null && searchResult.getData() != null, "SearchResult is invalid.");
String keywordsToSearch = queryWord;
String spellingCorrentWord = null, dest = null;
if (containsProductInSearchResult(searchResult)) {
// 1) 搜索有结果的 优先从搜索结果聚合出品牌等关键词进行查询
JSONObject dataMap = ((JSONObject) searchResult.getData());
... ... @@ -103,25 +104,18 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
if (StringUtils.isEmpty(keywordsToSearch)) {
return defaultSuggestRecommendation();
}
} else if (allowSpellingCorrent(queryWord) && StringUtils.isNotEmpty((spellingCorrentWord = suggestService.getSpellingCorrectKeyword(queryWord)))) {
// 3) 执行拼写检查 由于在搜索建议的时候会进行拼写检查 所以缓存命中率高
keywordsToSearch = spellingCorrentWord;
} else if (allowGetingDest(queryWord) && StringUtils.isNotEmpty((dest = getSuggestConversionDestBySource(queryWord)))) {
// 4) 爬虫和自定义的Conversion处理
keywordsToSearch = dest;
} else {
// 3) 搜索没有结果的,考虑拼写纠错、爬虫Conversion和词太多的情况
// 3.1) 执行拼写检查 由于在搜索建议的时候会进行拼写检查 所以缓存命中率高
String spellingCorrentWord = suggestService.getSpellingCorrectKeyword(queryWord);
// 3.2) 爬虫和自定义的Conversion处理
String dest = CUSTOM_SUGGEST_CONVERSIONS.get(queryWord.trim().toLowerCase());
dest = dest != null ? dest : getSuggestConversionDestBySource(queryWord);
// 3.3) 如果两者都没有 则还是使用原先的用户输入queryWord
if (StringUtils.isNotEmpty(spellingCorrentWord) || StringUtils.isNotEmpty(dest)) {
keywordsToSearch = new StringBuilder()
.append(StringUtils.isNotEmpty(spellingCorrentWord) ? spellingCorrentWord : "")
.append(StringUtils.isNotEmpty(dest) ? dest : "").toString();
}
// 5) 如果两者都没有 则还是使用原先的用户输入queryWord
}
JSONObject recommendResult = recommendBySuggestIndex(paramMap, keywordsToSearch);
if(recommendResult == null || CollectionUtils.isEmpty((List)recommendResult.get("terms_suggestion"))){
if (recommendResult == null || CollectionUtils.isEmpty((List) recommendResult.get("terms_suggestion"))) {
recommendResult = defaultSuggestRecommendation();
}
... ... @@ -132,10 +126,30 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
}
}
private boolean allowGetingDest(String queryWord) {
// 对于conversion长度要求在[2,10]之间
return queryWord.length() >= 2 && queryWord.length() <= 10;
}
private boolean allowSpellingCorrent(String queryWord) {
// 对于拼写检查长度要求在[4,20]之间
if (queryWord.length() < 4 || queryWord.length() > 20) {
return false;
}
// 不能有空格、加号、逗号等符号
if (queryWord.contains(" ") || queryWord.contains("+") || queryWord.contains(",") || queryWord.contains("%")) {
return false;
}
return true;
}
/**
* 根据计算获取的推荐词列表到suggest索引获取推荐词。
* 多个词的情况下优先会给匹配到更多term的词加分。
* @param paramMap 搜索参数,用于判断取哪个count
*
* @param paramMap 搜索参数,用于判断取哪个count
* @param keywordsToSearch 计算获取的推荐词列表
* @return 搜推荐结果
*/
... ... @@ -278,6 +292,7 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
/**
* 根据SKN到productindex索引获取搜索结果,然后聚合出推荐词列表。
*
* @param queryWord 搜索的关键词
* @return 推荐词列表
*/
... ... @@ -301,7 +316,7 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
JSONObject jsonObject = searchCacheService.getJSONObjectFromCache(indexName, productIndexSearchParam);
if (jsonObject != null) {
CACHE_MATCH_REQUEST.info("match cache for product list terms suggestion by skns, sknList = {}.", sknList);
CACHE_MATCH_REQUEST.info("match cache for product list search recommendation by skns, sknList = {}.", sknList);
return jsonObject.getString("aggKeyword");
}
... ... @@ -334,6 +349,7 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
/**
* 根据搜索的关键词到conversion索引查询关联的关键词。
* 该索引包含了爬虫提取的关键词、品牌的关键词定义和自定义的关键词。
*
* @param queryWord 搜索的关键词
* @return 推荐关键词列表
*/
... ... @@ -341,16 +357,14 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
long begin = System.currentTimeMillis();
logger.info("[func=getSuggestConversionDestBySource][query={}][begin={}]", queryWord, begin);
// 2) 根据terms搜索构造搜索请求
SearchParam searchParam = new SearchParam();
MatchQueryBuilder queryBuilder = QueryBuilders.matchQuery("source", queryWord);
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder);
// 2.1) 优先取完全匹配的Term
functionScoreQueryBuilder.add(QueryBuilders.termQuery("source.source_keyword", queryWord.trim().toLowerCase()),
ScoreFunctionBuilders.weightFactorFunction(100));
functionScoreQueryBuilder.boostMode(CombineFunction.MULT);
// 1) 先检查自定义的配置
if (CUSTOM_SUGGEST_CONVERSIONS.containsKey(queryWord.trim().toLowerCase())) {
return CUSTOM_SUGGEST_CONVERSIONS.get(queryWord.trim().toLowerCase());
}
searchParam.setQuery(functionScoreQueryBuilder);
// 2) 根据terms搜索构造搜索请求 要求完全匹配source
SearchParam searchParam = new SearchParam();
searchParam.setQuery(QueryBuilders.termQuery("source.source_keyword", queryWord.trim().toLowerCase()));
searchParam.setPage(1);
searchParam.setSize(1);
searchParam.setFiter(QueryBuilders.termQuery("status", 1));
... ... @@ -359,7 +373,7 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
final String indexName = ISearchConstants.INDEX_NAME_CONVERSION;
JSONObject suggestResult = searchCacheService.getJSONObjectFromCache(indexName, searchParam);
if (suggestResult != null) {
CACHE_MATCH_REQUEST.info("match cache for product list terms suggestion by conversion, keyword = {}.", queryWord);
CACHE_MATCH_REQUEST.info("match cache for product list search recommendation by conversion, keyword = {}.", queryWord);
return suggestResult.getString("dest");
}
... ... @@ -372,8 +386,9 @@ public class SearchRecommendServiceImpl implements ISearchRecommendService {
String dest = "";
if (CollectionUtils.isNotEmpty(searchResult.getResultList())) {
// 5) 从conversion获取的keyword列表
String source = (String) searchResult.getResultList().get(0).get("source");
dest = (String) searchResult.getResultList().get(0).get("dest");
logger.info("[func=getSuggestConversionDestBySource][source={}][dest={}]", searchResult.getResultList().get(0).get("source"), dest);
logger.info("[func=getSuggestConversionDestBySource][source={}][dest={}]", source, dest);
}
// 6) 加入缓存
... ...