...
|
...
|
@@ -8,6 +8,7 @@ import com.yoho.search.base.utils.Transfer; |
|
|
import com.yoho.search.core.es.model.SearchParam;
|
|
|
import com.yoho.search.core.es.model.SearchResult;
|
|
|
import com.yoho.search.models.SearchApiResult;
|
|
|
import com.yoho.search.recall.common.ABUserPartitionUtils;
|
|
|
import com.yoho.search.recall.scene.beans.builder.UserRecallRequestBuilder;
|
|
|
import com.yoho.search.recall.scene.beans.cache.SknReturnInfoCacheBean;
|
|
|
import com.yoho.search.recall.scene.beans.cache.UserRecallCacheBean;
|
...
|
...
|
@@ -53,6 +54,7 @@ public class SceneRecallProductListService { |
|
|
|
|
|
/**
|
|
|
* 个性化召回列表入口1
|
|
|
*
|
|
|
* @param paramMap
|
|
|
* @return
|
|
|
*/
|
...
|
...
|
@@ -76,6 +78,7 @@ public class SceneRecallProductListService { |
|
|
|
|
|
/**
|
|
|
* 个性化召回列表入口2
|
|
|
*
|
|
|
* @param userRecallRequest
|
|
|
* @param page
|
|
|
* @return
|
...
|
...
|
@@ -83,17 +86,17 @@ public class SceneRecallProductListService { |
|
|
public SearchApiResult recallProductList(UserRecallRequest userRecallRequest, int page) {
|
|
|
//1、判断第一页是要需要查缓存【不查询缓存时,只添加缓存,以保证用户数据的实时性】
|
|
|
boolean ignoreQueryCache = false;
|
|
|
if(page==1 && userRecallRequest.hasUidOrUdid() && !searchDynamicConfigService.searchPersionalNewStrategyFirstPageCacheOpen()){
|
|
|
if (page == 1 && userRecallRequest.hasUidOrUdid() && !searchDynamicConfigService.searchPersionalNewStrategyFirstPageCacheOpen()) {
|
|
|
ignoreQueryCache = true;
|
|
|
}
|
|
|
|
|
|
//2、执行召回
|
|
|
long begin = System.currentTimeMillis();
|
|
|
UserRecallResponse userRecallResponse = userRecallCacheBean.queryRecallResult(userRecallRequest,ignoreQueryCache);
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[1]-queryRecallResult,cost is [{}]", System.currentTimeMillis()-begin);
|
|
|
UserRecallResponse userRecallResponse = userRecallCacheBean.queryRecallResult(userRecallRequest, ignoreQueryCache);
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[1]-queryRecallResult,cost is [{}]", System.currentTimeMillis() - begin);
|
|
|
|
|
|
//3、根据召回结果查询商品信息
|
|
|
List<Map<String, Object>> productList = this.queryProductList(userRecallRequest, userRecallResponse,page, userRecallRequest.getPageSize());
|
|
|
List<Map<String, Object>> productList = this.queryProductList(userRecallRequest, userRecallResponse, page, userRecallRequest.getPageSize());
|
|
|
|
|
|
//4、构造返回结果
|
|
|
JSONObject dataMap = new JSONObject();
|
...
|
...
|
@@ -107,6 +110,7 @@ public class SceneRecallProductListService { |
|
|
|
|
|
/**
|
|
|
* 根据召回结果查询商品列表
|
|
|
*
|
|
|
* @param userRecallRequest
|
|
|
* @param userRecallResponse
|
|
|
* @param page
|
...
|
...
|
@@ -118,33 +122,33 @@ public class SceneRecallProductListService { |
|
|
int recallTotalPage = userRecallResponse.getRecallTotalPage();
|
|
|
//2、在召回结果中则直接根据skn去查询
|
|
|
List<RecallSknInfo> recallSknInfos = null;
|
|
|
if(page<=recallTotalPage){
|
|
|
recallSknInfos = CollectionUtils.safeSubList(userRecallResponse.getSknList(),(page-1)*pageSize,page*pageSize);
|
|
|
}else{
|
|
|
recallSknInfos = this.queryProductSknByFilterSkn(userRecallRequest, userRecallResponse.getSknList(), page-recallTotalPage, pageSize);
|
|
|
if (page <= recallTotalPage) {
|
|
|
recallSknInfos = CollectionUtils.safeSubList(userRecallResponse.getSknList(), (page - 1) * pageSize, page * pageSize);
|
|
|
} else {
|
|
|
recallSknInfos = this.queryProductSknByFilterSkn(userRecallRequest, userRecallResponse.getSknList(), page - recallTotalPage, pageSize);
|
|
|
}
|
|
|
//3、获取召回结果的skn
|
|
|
List<Integer> productSknList = this.getProductSknList(recallSknInfos);
|
|
|
|
|
|
//4、获取商品的返回信息
|
|
|
long begin = System.currentTimeMillis();
|
|
|
List<Map<String, Object>> productInfoList = sknReturnInfoCacheBean.queryProductListBySkn(productSknList,productSknList.size());
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[2].queryProductListBySkn,cost is [{}]", System.currentTimeMillis()-begin);
|
|
|
List<Map<String, Object>> productInfoList = sknReturnInfoCacheBean.queryProductListBySkn(productSknList, productSknList.size());
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[2].queryProductListBySkn,cost is [{}]", System.currentTimeMillis() - begin);
|
|
|
|
|
|
//5、填充召回类型
|
|
|
Map<Integer,RecallSknInfo> sknRecallTypeMap = CollectionUtils.toMap(recallSknInfos, new Transfer<RecallSknInfo, Integer>() {
|
|
|
Map<Integer, RecallSknInfo> sknRecallTypeMap = CollectionUtils.toMap(recallSknInfos, new Transfer<RecallSknInfo, Integer>() {
|
|
|
@Override
|
|
|
public Integer transfer(RecallSknInfo recallSknInfo) {
|
|
|
return recallSknInfo.getProductSkn();
|
|
|
}
|
|
|
});
|
|
|
for(Map<String, Object> productInfo: productInfoList){
|
|
|
int productSkn = MapUtils.getIntValue(productInfo,"product_skn",0);
|
|
|
for (Map<String, Object> productInfo : productInfoList) {
|
|
|
int productSkn = MapUtils.getIntValue(productInfo, "product_skn", 0);
|
|
|
RecallSknInfo recallSknInfo = sknRecallTypeMap.get(productSkn);
|
|
|
if(recallSknInfo==null || recallSknInfo.getRecallType()==null){
|
|
|
productInfo.put("recall_type", StrategyEnum.DEFAULT.name());
|
|
|
}else{
|
|
|
productInfo.put("recall_type",recallSknInfo.getRecallType());
|
|
|
if (recallSknInfo == null || recallSknInfo.getRecallType() == null) {
|
|
|
productInfo.put("recall_type", StrategyEnum.DEFAULT_HEAT_VALUE.name());
|
|
|
} else {
|
|
|
productInfo.put("recall_type", recallSknInfo.getRecallType());
|
|
|
}
|
|
|
}
|
|
|
return productInfoList;
|
...
|
...
|
@@ -152,53 +156,57 @@ public class SceneRecallProductListService { |
|
|
|
|
|
/**
|
|
|
* 过滤掉已召回的skn,并按人气排序
|
|
|
*
|
|
|
* @param recallSknInfos
|
|
|
* @param realPage
|
|
|
* @param pageSize
|
|
|
* @return
|
|
|
*/
|
|
|
private List<RecallSknInfo> queryProductSknByFilterSkn(UserRecallRequest userRecallRequest, List<RecallSknInfo> recallSknInfos, int realPage, int pageSize){
|
|
|
private List<RecallSknInfo> queryProductSknByFilterSkn(UserRecallRequest userRecallRequest, List<RecallSknInfo> recallSknInfos, int realPage, int pageSize) {
|
|
|
long begin = System.currentTimeMillis();
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
//0、策略区分
|
|
|
StrategyEnum strategyEnum = ABUserPartitionUtils.isAUserComplete(userRecallRequest.getUid(), userRecallRequest.getUdid()) ? StrategyEnum.DEFAULT_HEAT_VALUE : StrategyEnum.DEFAULT_CTR_VALUE;
|
|
|
|
|
|
//1、设置query
|
|
|
SearchParam searchParam = new SearchParam();
|
|
|
searchParam.setQuery(userRecallRequest.getParamQueryFilter().getParamQuery());
|
|
|
|
|
|
//2、设置filter
|
|
|
List<Integer> notProductSkns = new ArrayList<>();
|
|
|
for (RecallSknInfo recallSknInfo:recallSknInfos ){
|
|
|
for (RecallSknInfo recallSknInfo : recallSknInfos) {
|
|
|
notProductSkns.add(recallSknInfo.getProductSkn());
|
|
|
}
|
|
|
BoolQueryBuilder filter = userRecallRequest.getParamQueryFilter().getParamFilter();
|
|
|
filter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.productSkn,notProductSkns));
|
|
|
filter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, notProductSkns));
|
|
|
searchParam.setFiter(filter);
|
|
|
|
|
|
//3、设置分页参数
|
|
|
searchParam.setOffset((realPage-1)*pageSize);
|
|
|
searchParam.setOffset((realPage - 1) * pageSize);
|
|
|
searchParam.setSize(pageSize);
|
|
|
|
|
|
//4、设置IncludeFields
|
|
|
searchParam.setIncludeFields(Arrays.asList(ProductIndexEsField.productSkn));
|
|
|
|
|
|
//5、设置排序
|
|
|
List<SortBuilder<?>> sortBuilders = new ArrayList<>();
|
|
|
if (strategyEnum.equals(StrategyEnum.DEFAULT_HEAT_VALUE)) {
|
|
|
sortBuilders.add(SortBuilderHelper.getHeatValueDescSort());
|
|
|
} else {
|
|
|
sortBuilders.add(SortBuilderHelper.getCtrValueDescSort());
|
|
|
}
|
|
|
sortBuilders.add(SortBuilderHelper.getSevendayMoneyDescSort());
|
|
|
sortBuilders.add(SortBuilderHelper.getIdDescSort());
|
|
|
searchParam.setSortBuilders(sortBuilders);
|
|
|
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX,searchParam);
|
|
|
|
|
|
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
|
|
|
//6、构造返回结果
|
|
|
List<RecallSknInfo> results = new ArrayList<>();
|
|
|
for (Map<String, Object> product : searchResult.getResultList()) {
|
|
|
results.add(new RecallSknInfo(MapUtils.getIntValue(product,ProductIndexEsField.productSkn,0), StrategyEnum.DEFAULT.name()));
|
|
|
results.add(new RecallSknInfo(MapUtils.getIntValue(product, ProductIndexEsField.productSkn, 0), strategyEnum.name()));
|
|
|
}
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[1.5].queryProductSknByFilterSkn,cost is [{}]", System.currentTimeMillis()-begin);
|
|
|
|
|
|
RECALL_NEW_LOGGER.info("SceneRecallProductListService[1.5].queryProductSknByFilterSkn,cost is [{}]", System.currentTimeMillis() - begin);
|
|
|
return results;
|
|
|
}
|
|
|
|
|
|
private List<Integer> getProductSknList(List<RecallSknInfo> recallSknInfos){
|
|
|
private List<Integer> getProductSknList(List<RecallSknInfo> recallSknInfos) {
|
|
|
List<Integer> productSknList = new ArrayList<>();
|
|
|
for (RecallSknInfo recallSknInfo:recallSknInfos ){
|
|
|
for (RecallSknInfo recallSknInfo : recallSknInfos) {
|
|
|
productSknList.add(recallSknInfo.getProductSkn());
|
|
|
}
|
|
|
return productSknList;
|
...
|
...
|
|