Authored by wangnan9279

ufo搜索建议词 fix

... ... @@ -17,7 +17,6 @@ import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
/**
... ... @@ -30,7 +29,6 @@ public class UfoSuggestJob implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger("FLOW_EXECUTOR");
private List<RetryBusinessFlowExecutor> discoveryFlowExecutorList = new ArrayList<>();
//private List<RetryBusinessFlowExecutor> counterFlowExecutorList = new ArrayList<>();
@Autowired
private UfoSuggestCache suggestionCache;
... ... @@ -47,20 +45,12 @@ public class UfoSuggestJob implements ApplicationContextAware {
.sorted((discoverer1, discoverer2) -> discoverer1.getKeywordType().compare(discoverer2.getKeywordType()))
.map(counter -> new RetryBusinessFlowExecutor(counter, consumerConfiger.getUfoSuggestionDiscoverBatchMaxThreadSize(), consumerConfiger.getUfoSuggestionDiscoverBatchLimit()))
.collect(Collectors.toList());
// Map<String, UfoAbstractSuggestionCounter> countBeanMap = applicationContext.getBeansOfType(UfoAbstractSuggestionCounter.class);
// Assert.isTrue(countBeanMap != null && !countBeanMap.isEmpty(), "There is no ufo suggestion counter defined.");
// counterFlowExecutorList = countBeanMap.values().stream()
// .map(counter -> new RetryBusinessFlowExecutor(counter, consumerConfiger.getUfoSuggestionCountBatchMaxThreadSize(), consumerConfiger.getUfoSuggestionCountBatchLimit()))
// .collect(Collectors.toList());
}
@Scheduled(cron = "0 0 6 * * ?")
public void executeAll() {
executeDiscovery();
safeSleep();
//executeCounter();
//safeSleep();
indexRebuildJob.rebuildUfoSuggestIndex();
}
... ... @@ -85,42 +75,6 @@ public class UfoSuggestJob implements ApplicationContextAware {
}
}
// private void executeCounter() {
// long begin = System.currentTimeMillis();
// logger.info("UfoSuggestionJob executeCounter start [begin={}]", begin);
// boolean result = true;
// for (RetryBusinessFlowExecutor executor : counterFlowExecutorList) {
// boolean tempResult = executor.execute();
// if (!tempResult) {
// logger.warn("UfoSuggestionJob executeCounter has failure [bean={}]", executor.getFlowName());
// }
// result = result && tempResult;
// }
// logger.info("SuggestionJob.executeCounter end [cost={}][result={}]", (System.currentTimeMillis() - begin), result);
// }
public void executeDiscoveryForSingleFlow(String flowName) {
try {
long begin = System.currentTimeMillis();
logger.info("SuggestionJob.executeDiscoveryForSingleFlow start----[begin={}]", begin);
suggestionCache.init();
Optional<RetryBusinessFlowExecutor> executor = discoveryFlowExecutorList.stream().filter(item -> flowName.equals(item.getFlowName())).findAny();
executor.ifPresent(RetryBusinessFlowExecutor::execute);
logger.info("SuggestionJob.executeDiscoveryForSingleFlow end----[cost={}]", (System.currentTimeMillis() - begin));
} finally {
suggestionCache.cleanup();
}
}
// public void executeCounterForSingleFlow(String flowName) {
// long begin = System.currentTimeMillis();
// logger.info("SuggestionJob.executeCounter start----[begin={}]", begin);
// Optional<RetryBusinessFlowExecutor> executor = counterFlowExecutorList.stream().filter(item -> flowName.equals(item.getFlowName())).findAny();
// executor.ifPresent(RetryBusinessFlowExecutor::execute);
// logger.info("SuggestionJob.executeCounter end----[cost={}]", (System.currentTimeMillis() - begin));
// }
private void safeSleep() {
try {
Thread.sleep(10000L);
... ...
... ... @@ -16,7 +16,7 @@ import java.util.concurrent.ConcurrentHashMap;
/**
* @author wangnan
* @Version 2019/6/4
* @version 2019/6/4
*/
@Component
public class UfoSuggestCache {
... ... @@ -59,7 +59,7 @@ public class UfoSuggestCache {
return oldValue == null;
}
public String generateIdentifier(String keyword) {
private String generateIdentifier(String keyword) {
if (StringUtils.isEmpty(keyword)) {
return "empty";
}
... ...
... ... @@ -21,7 +21,7 @@ import java.util.List;
public class UfoSuggestSearchParamBuilder {
@Autowired
private ConsumerConfiger configer;
private ConsumerConfiger config;
public SearchParam build(String keyword) {
SearchParam searchParam = new SearchParam();
... ... @@ -36,15 +36,15 @@ public class UfoSuggestSearchParamBuilder {
boolFilter.must(QueryBuilders.termQuery(UfoProductIndexEsField.delStatus, 0));
boolFilter.must(QueryBuilders.termQuery(UfoProductIndexEsField.shelveStatus, 1));
// 对男女关键字做特殊处理
boolean cotainBoy = keyword.contains("男");
boolean cotainGirl = keyword.contains("女");
boolean containBoy = keyword.contains("男");
boolean containGirl = keyword.contains("女");
// 对性别做特殊处理
String gender = null;
if (cotainBoy && !cotainGirl) {
if (containBoy && !containGirl) {
gender = "1,3";
} else if (!cotainBoy && cotainGirl) {
} else if (!containBoy && containGirl) {
gender = "2,3";
} else if (cotainBoy && cotainGirl) {
} else if (containBoy && containGirl) {
gender = "1,2,3";
}
if (gender != null) {
... ... @@ -65,9 +65,9 @@ public class UfoSuggestSearchParamBuilder {
queryBuilder.type(multiMatchQueryBuilderType);
}
setDefaultSearchField(queryBuilder);
if (configer.getSearchOperator().equalsIgnoreCase("or")) {
if (config.getSearchOperator().equalsIgnoreCase("or")) {
queryBuilder.operator(Operator.OR);
queryBuilder.minimumShouldMatch(configer.getSearchMinimumShouldMatch());
queryBuilder.minimumShouldMatch(config.getSearchMinimumShouldMatch());
} else {
queryBuilder.operator(Operator.AND);
}
... ... @@ -75,7 +75,7 @@ public class UfoSuggestSearchParamBuilder {
}
private MultiMatchQueryBuilder.Type getMultiMatchQueryBuilderType() {
String configMultiMatchQueryType = configer.getSearchMultiMatchQueryType();
String configMultiMatchQueryType = config.getSearchMultiMatchQueryType();
return SearchFieldUtils.getMultiMatchQueryBuilderType(configMultiMatchQueryType);
}
... ...
... ... @@ -26,7 +26,7 @@ public class UfoSuggestSplitUtils {
return results;
}
public static Set<String> splitProductName(String token) {
private static Set<String> splitProductName(String token) {
Set<String> results = new HashSet<String>();
if (StringUtils.isBlank(token)) {
return results;
... ...
... ... @@ -13,25 +13,23 @@ import java.util.stream.Stream;
public class UfoSuggestionConstants {
public static final Integer VALID_STATUS = 1;
public static final Set<String> IGNORE_KEYWORDS = Stream.of("")
.map(String::toLowerCase).collect(Collectors.toSet());
public static final Set<String> IGNORE_KEYWORDS = Stream.of("").map(String::toLowerCase).collect(Collectors.toSet());
public static final List<String> IGNORE_BRAND_NAMES = Arrays.asList("");
public static final int SMART_SUGGESTION_TERM_COUNT = 10;
public static final int SMART_SUGGESTION_PRODUCT_LIMIT = 20;
public static String UFO_SERIES_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.series.name.enable";
public static String UFO_BRAND_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brand.name.enable";
public static String UFO_SORT_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.sort.name.enable";
public static String UFO_PRODUCT_NAME_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.product.name.token.enable";
public static String UFO_PRODUCT_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.product.keyword.token.enable";
public static String UFO_BRAND_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.brand.keyword.token.enable";
public static String UFO_SERIES_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.series.keyword.token.enable";
public static String UFO_BRAND_AND_SORT_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brand.and.sort.name.enable";
public static String UFO_BRAND_AND_SERIES_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brand.and.series.name.enable";
public static String UFO_BRAND_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brandname.enable";
public static String UFO_SORT_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.sortname.enable";
public static String UFO_BRAND_AND_SORT_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brandwithsortname.enable";
public static String UFO_BRAND_AND_SERIES_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.brandwithseriesname.enable";
public static String UFO_PRODUCT_NAME_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.productname.token.enable";
public static String UFO_PRODUCT_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.productkeyword.token.enable";
public static String UFO_BRAND_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.brandkeyword.token.enable";
public static String UFO_SERIES_KEYWORD_TOKEN_ENABLED_KEY = "ufo.search.suggestion.consumer.brandkeyword.token.enable";
public static String UFO_SERIES_NAME_ENABLED_KEY = "ufo.search.suggestion.consumer.seriesname.enable";
}
... ...
package com.yoho.search.consumer.ufosuggests.counter;
import com.yoho.search.consumer.index.rebuild.RebuildFlagService;
import com.yoho.search.consumer.suggests.common.RetryBusinessFlow;
import com.yoho.search.consumer.suggests.counter.CountUsage;
import com.yoho.search.consumer.suggests.counter.KeywordCounterService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 建议词计数器 抽象类
* @author wangnan
* @version 2019/6/4
*/
public abstract class UfoAbstractSuggestionCounter implements ApplicationEventPublisherAware, RetryBusinessFlow {
protected static final Logger logger = LoggerFactory.getLogger("FLOW_EXECUTOR");
@Autowired
private KeywordCounterService keywordCounterService;
@Autowired
private RebuildFlagService rebuildFlagService;
protected ApplicationEventPublisher publisher;
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
@Override
public String flowName() {
return this.getClass().getSimpleName();
}
@Override
public void init() {
rebuildFlagService.waitingRebuildingIndex();
rebuildFlagService.updateIsBuildingTrue();
}
@Override
public boolean doBusiness(int pageNo, int batchSize) {
Map<String, Object> keywordMap = getKeywordMap(pageNo, batchSize);
int fetchSize = keywordMap != null ? keywordMap.size() : 0;
if (fetchSize == 0) {
logger.info("[{} business][pageNo={}][fetchWordSize={}]", flowName(), pageNo, fetchSize);
return true;
}
Map<String, Integer> countMapForApp = keywordCounterService.batchCount(keywordMap.keySet().stream().collect(Collectors.toList()), CountUsage.APP);
int countMapSizeForApp = countMapForApp != null ? countMapForApp.size() : 0;
if (countMapSizeForApp == 0) {
logger.info("[{} business][pageNo={}][countMapSizeForApp={}]", flowName(), pageNo, countMapSizeForApp);
return false;
}
Map<String, Integer> countMapForPC = keywordCounterService.batchCount(keywordMap.keySet().stream().collect(Collectors.toList()), CountUsage.PC);
int countMapSizeForPC = countMapForPC != null ? countMapForPC.size() : 0;
if (countMapSizeForPC == 0) {
logger.info("[{} business][pageNo={}][countMapForPC={}]", flowName(), pageNo, countMapSizeForPC);
return false;
}
Map<String, Integer> countMapForBlk = keywordCounterService.batchCount(keywordMap.keySet().stream().collect(Collectors.toList()), CountUsage.BLK);
int countMapSizeForBlk = countMapForBlk != null ? countMapForBlk.size() : 0;
if (countMapSizeForBlk == 0) {
logger.info("[{} business][pageNo={}][countMapSizeForBlk={}]", flowName(), pageNo, countMapSizeForBlk);
return false;
}
logger.info("[{} business][pageNo={}][fetchWordSize={}][countMapSizeForApp={}][countMapSizeForPC={}][countMapSizeForBlk={}]",
flowName(), pageNo, fetchSize, countMapSizeForApp, countMapSizeForPC, countMapSizeForBlk);
return persistence(keywordMap, countMapForApp, countMapForPC, countMapForBlk);
}
protected Integer calCount(Map<String, Integer> countResultMap, String suggestWord) {
Integer count = countResultMap.get(suggestWord);
return count != null ? count : Integer.valueOf(0);
}
@Override
public void finish(boolean doBusinessResult, Exception exception) {
rebuildFlagService.updateIsBuildingFalse();
}
abstract Map<String, Object> getKeywordMap(int pageNo, int batchSize);
abstract boolean persistence(Map<String, Object> keywordMap, Map<String, Integer> countMapForApp, Map<String, Integer> countMapForPC, Map<String, Integer> countMapForBlk);
}
package com.yoho.search.consumer.ufosuggests.counter;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.consumer.common.IYohoIndexService;
import com.yoho.search.consumer.suggests.common.SuggestSearchParamBuilder;
import com.yoho.search.consumer.suggests.counter.CountUsage;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.dal.model.SuggestWordDef;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 关键词计数器
* @author wangnan
* @version 2019/6/4
*/
@Component
public class UfoKeywordCounterService {
@Autowired
private IYohoIndexService yohoIndexService;
@Autowired
private SuggestSearchParamBuilder suggestSearchParamBuilder;
public Map<String, Integer> batchCount(List<String> keywords, CountUsage countUsage) {
Assert.notNull(keywords);
Map<String, Integer> countResultMap = new LinkedHashMap<>();
List<SearchParam> searchParams = keywords.stream().map(keyword -> suggestSearchParamBuilder.build(keyword, countUsage)).collect(Collectors.toList());
List<SearchResult> results = yohoIndexService.multiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
Assert.notNull(results);
Assert.isTrue(results.size() == keywords.size());
for (int i = 0; i < keywords.size(); i++) {
countResultMap.put(keywords.get(i), Integer.valueOf(String.valueOf(results.get(i).getTotal())));
}
return countResultMap;
}
public SuggestWordDef countKeyword(String keyword) {
Assert.notNull(keyword);
List<SearchParam> searchParams = new ArrayList<>();
searchParams.add(suggestSearchParamBuilder.build(keyword, CountUsage.PC));
searchParams.add(suggestSearchParamBuilder.build(keyword, CountUsage.APP));
searchParams.add(suggestSearchParamBuilder.build(keyword, CountUsage.BLK));
List<SearchResult> results = yohoIndexService.multiSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParams);
Assert.notNull(results);
Assert.isTrue(results.size() == 3);
SuggestWordDef suggestWordDef = new SuggestWordDef();
suggestWordDef.setKeyword(keyword);
suggestWordDef.setCount(Integer.valueOf(String.valueOf(results.get(0).getTotal())));
suggestWordDef.setCountForApp(Integer.valueOf(String.valueOf(results.get(1).getTotal())));
suggestWordDef.setCountForBlk(Integer.valueOf(String.valueOf(results.get(2).getTotal())));
return suggestWordDef;
}
}
package com.yoho.search.consumer.ufosuggests.counter;
import com.yoho.search.consumer.common.ConsumerDynamicConfigService;
import com.yoho.search.consumer.service.daoService.ufo.UfoSuggestWordService;
import com.yoho.search.consumer.suggests.common.KeywordType;
import com.yoho.search.consumer.suggests.common.SuggestionConstants;
import com.yoho.search.consumer.ufosuggests.common.UfoKeywordType;
import com.yoho.search.dal.model.UfoSuggestWord;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 建议词计数器
* @author wangnan
* @version 2019/6/5
*/
@Component
public class UfoSuggestWordCounter extends UfoAbstractSuggestionCounter {
@Autowired
private UfoSuggestWordService suggestWordService;
@Autowired
private ConsumerDynamicConfigService consumerDynamicConfigService;
@Override
public int getTotalCount() {
return suggestWordService.selectTotalCount();
}
@Override
Map<String, Object> getKeywordMap(int pageNo, int batchSize) {
int start = (pageNo - 1) * batchSize;
Map<String, Object> wordMap = new HashMap<>(batchSize);
List<UfoSuggestWord> dataList = suggestWordService.selectPageList(start, batchSize);
if (CollectionUtils.isNotEmpty(dataList)) {
Set<Integer> enabledKeywordTypes = Stream.of(UfoKeywordType.values()).filter(keywordType -> consumerDynamicConfigService.ufoSuggestKeywordTypeOpen(keywordType))
.map(UfoKeywordType::getType).collect(Collectors.toSet());
dataList.stream().filter(item -> SuggestionConstants.VALID_STATUS.equals(item.getStatus())).filter(item -> enabledKeywordTypes.contains(item.getType()))
.forEach(item -> wordMap.put(item.getKeyword(), item));
}
return wordMap;
}
@Override
boolean persistence(Map<String, Object> keywordMap, Map<String, Integer> countMapForApp, Map<String, Integer> countMapForPC, Map<String, Integer> countMapForBlk) {
List<UfoSuggestWord> batchList = new ArrayList<>(countMapForApp.size());
countMapForApp.forEach((keyword, count) -> {
UfoSuggestWord ufoSuggestWord = (UfoSuggestWord) keywordMap.get(keyword);
if (ufoSuggestWord != null) {
ufoSuggestWord.setCount(calCount(countMapForPC, keyword));
ufoSuggestWord.setWeight(KeywordType.getWeightValueByType(ufoSuggestWord.getType()));
batchList.add(ufoSuggestWord);
}
});
suggestWordService.updateBatch(batchList);
return true;
}
}
... ... @@ -7,7 +7,7 @@ import com.yoho.search.core.es.agg.IAggregation;
import org.springframework.stereotype.Component;
/**
* 商品关键词词条发现器
* 商品名称词条发现器
* @author wangnan
* @version 2019/6/4
*/
... ...
... ... @@ -53,16 +53,8 @@ public class ConsumerConfiger {
}
/******************************for UFO Suggestion**************************************/
public int getUfoSuggestionCountBatchLimit (){
return configurer.getInt("ufo.suggestion.count.batch.limit", 300);
}
public int getUfoSuggestionCountBatchMaxThreadSize(){
return configurer.getInt("ufo.suggestion.count.batch.max.thread.size", 1);
}
public int getUfoSuggestionDiscoverBatchLimit(){
return configurer.getInt("ufo.suggestion.discover.batch.limit", 500);
return configurer.getInt("ufo.suggestion.discover.batch.limit", 300);
}
public int getUfoSuggestionDiscoverBatchMaxThreadSize(){
... ...
... ... @@ -38,5 +38,9 @@ suggestion.discover.batch.max.thread.size=3
suggestion.count.agg.size=10000
suggestion.count.agg.mindoc=5
#ufo suggestion
ufo.suggestion.discover.batch.limit=500
ufo.suggestion.discover.batch.max.thread.size=3
#not log profile.threshold
profile.threshold=10000000
... ...
... ... @@ -38,5 +38,9 @@ suggestion.discover.batch.max.thread.size=${suggestion.discover.batch.max.thread
suggestion.count.agg.size=${suggestion.count.agg.size}
suggestion.count.agg.mindoc=${suggestion.count.agg.mindoc}
#ufo suggestion
ufo.suggestion.discover.batch.limit=${ufo.suggestion.discover.batch.limit}
ufo.suggestion.discover.batch.max.thread.size=${ufo.suggestion.discover.batch.max.thread.size}
#not log profile.threshold
profile.threshold=10000000
... ...