Authored by hugufei

新列表召回代码优化

... ... @@ -2,175 +2,76 @@ package com.yoho.search.recall.scene;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.recall.scene.component.*;
import com.yoho.search.recall.scene.models.*;
import com.yoho.search.recall.scene.persional.PersionalFactor;
import com.yoho.search.recall.scene.persional.RecallPersionalService;
import com.yoho.search.recall.scene.request.BrandRecallRequestBuilder;
import com.yoho.search.recall.scene.request.CommonRecallRequestBuilder;
import com.yoho.search.recall.scene.request.SortPriceRecallRequestBuilder;
import com.yoho.search.recall.scene.strategy.StrategyNameEnum;
import com.yoho.search.recall.sort.helper.RecallServiceHelper;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.helper.SearchServiceHelper;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class SceneRecallService {
private static final Logger logger = LoggerFactory.getLogger(SceneRecallService.class);
@Autowired
private SearchServiceHelper searchServiceHelepr;
private RecallParamsBuilder recallParamsBuilder;
@Autowired
private RecallPersionalService recallPersionalService;
@Autowired
private CommonRecallRequestBuilder commonRequestBuilder;
@Autowired
private BrandRecallRequestBuilder brandRequestBuilder;
@Autowired
private SortPriceRecallRequestBuilder sortPriceRequestBuilder;
private BatchRequestsBuilder batchRequestsBuilder;
@Autowired
private RecallCommonService recallCommonService;
private BatchRecallComponent bacthRecallComponent;
@Autowired
private RecallServiceHelper recallServiceHelper;
private BatchResponseBuilder batchResponseBuilder;
@Autowired
private SearchCommonHelper searchCommonHelper;
private RecallResultBuilder recallResultBuilder;
public SearchApiResult sceneRecall(Map<String, String> paramMap) {
try {
//1、分页参数验证
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
int page = MapUtils.getIntValue(paramMap, "page", 10);
int pageSize = MapUtils.getIntValue(paramMap, "viewNum", 10);
if (page < 1 || pageSize < 0 || page * pageSize > 1000000) {
return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
}
//2、构造召回相关参数
RecallParams recallParams = this.buildRecallParams(paramMap);
//3、执行召回
RecallResponseBatch recallResponseBatch = this.doBatchRecall(recallParams);
//4、构造返回结果
RecallParams recallParams = recallParamsBuilder.buildRecallParams(paramMap);
//3、获取个性化因子
PersionalFactor persionalFactor = recallPersionalService.queryPersionalFactor(recallParams);
//4、执行召回
RecallResult recallResult = this.doRecall(recallParams, persionalFactor);
//TODO
//5、构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", recallResponseBatch.getTotal());
dataMap.put("page", page);
dataMap.put("page_size", pageSize);
dataMap.put("page_total", searchCommonHelper.getTotalPage(recallResponseBatch.getTotal(), pageSize));
dataMap.put("product_list", recallResponseBatch.getSknList());
dataMap.put("product_list_size", recallResponseBatch.getSknList().size());
dataMap.put("total", recallResult.getTotal());
dataMap.put("page", recallResult.getPage());
dataMap.put("page_size", recallResult.getPageSize());
dataMap.put("page_total", recallResult.getPageTotal());
dataMap.put("product_list", recallResult.getSknList());
return new SearchApiResult().setData(dataMap);
} catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setCode(500).setMessage("Exception");
}
}
private RecallParams buildRecallParams(Map<String, String> paramMap) throws Exception {
//1、获取连接中的query和filter参数
QueryBuilder query = searchServiceHelepr.constructQueryBuilder(paramMap);
BoolQueryBuilder filter = searchServiceHelepr.constructFilterBuilder(paramMap, null);
ParamQueryFilter paramQueryFilter = new ParamQueryFilter(query,filter);
//2、获取firstSkn参数
List<String> firstProductSkns = recallServiceHelper.getFirstProductSkns(paramMap);
//3、虎丘分页参数
int pageSize = MapUtils.getIntValue(paramMap, "viewNum", 10);
//4、获取uid或udid
int uid = MapUtils.getIntValue(paramMap, "uid", 1);
String udid = MapUtils.getString(paramMap, "udid", "");
return new RecallParams(paramQueryFilter, firstProductSkns, pageSize, uid, udid);
}
private RecallResponseBatch doBatchRecall(RecallParams param) {
//1、构造召回请求
List<RecallRequest> allRequests = this.buildRecallRequests(param);
private RecallResult doRecall(RecallParams param, PersionalFactor persionalFactor) {
//1、构造请求
List<RecallRequest> batchRequests = batchRequestsBuilder.buildBatchRequests(param, persionalFactor);
//2、批量召回
List<RecallRequestResponse> requestResponses = recallCommonService.batchRecallAndCache(allRequests);
//3、从兜底类型中获取总数
long total = this.getTotalCount(requestResponses);
//4、获取召回的skn
List<RecallResponseBatch.SknResult> sknResults = this.distinctRecallSkn(requestResponses);
//5、构造返回结果
return new RecallResponseBatch(total, sknResults);
}
private List<RecallRequest> buildRecallRequests(RecallParams param) {
//1、构造召回请求
List<RecallRequest> allRequests = new ArrayList<>();
//2、构造非个性化的请求
List<RecallRequest> commonRequests = commonRequestBuilder.buildCommonRecallRequests(param.getParamQueryFilter(), param.getFirstProductSkns(), param.getPageSize());
allRequests.addAll(commonRequests);
//3、获取个性化因子
PersionalFactor persionalFactor = recallPersionalService.queryPersionalFactor(param.getParamQueryFilter(), param.getUid(), param.getUdid());
//4、构建个性化品牌的召回请求
List<RecallRequest> brandRequests = brandRequestBuilder.buildBrandRecallRequests(param.getParamQueryFilter(), persionalFactor.getBrandIds());
allRequests.addAll(brandRequests);
//5、构建个性化品牌的召回请求
List<RecallRequest> sortPriceRequests = sortPriceRequestBuilder.buildSortPriceRecallRequests(param.getParamQueryFilter(), persionalFactor.getSortPriceAreas());
allRequests.addAll(sortPriceRequests);
return allRequests;
}
/**
* 从兜底类型中获取总数
*
* @param requestResponses
* @return
*/
private long getTotalCount(List<RecallRequestResponse> requestResponses) {
long total = 0;
for (RecallRequestResponse requestResponse : requestResponses) {
RecallRequest request = requestResponse.getRequest();
RecallResponse response = requestResponse.getResponse();
if (request ==null || response == null) {
continue;
}
if (StrategyNameEnum.COMMON.name().equalsIgnoreCase(request.requestType())){
total = response.getTotal();
break;
}
}
return total;
}
/**
* 召回结果去重
*
* @param requestResponses
* @return
*/
private List<RecallResponseBatch.SknResult> distinctRecallSkn(List<RecallRequestResponse> requestResponses) {
List<RecallResponseBatch.SknResult> sknResults = new ArrayList<>();
Map<Integer,List<String>> sknRequestMaps = new HashMap<>();
for (RecallRequestResponse requestResponse : requestResponses) {
RecallRequest request = requestResponse.getRequest();
RecallResponse response = requestResponse.getResponse();
if (request==null || response == null || response.getSkns()==null){
continue;
}
for (RecallResponse.RecallSkn recallSkn : response.getSkns()) {
List<String> requestTypes = sknRequestMaps.get(recallSkn.getSkn());
if(requestTypes==null){
sknResults.add(new RecallResponseBatch.SknResult(recallSkn));
requestTypes = new ArrayList<>();
sknRequestMaps.put(recallSkn.getSkn(),requestTypes);
}
requestTypes.add(request.requestType());
}
}
for (RecallResponseBatch.SknResult sknResult:sknResults) {
sknResult.setRequestTypes(sknRequestMaps.get(sknResult.getProductSkn()));
}
return sknResults;
List<RecallRequestResponse> requestResponses = bacthRecallComponent.batchRecallAndCache(batchRequests);
//3、获取skn列表[去重]
RecallResponseBatch recallResponseBatch = batchResponseBuilder.buildRecallResponseBatch(requestResponses);
//4、构造真实结果[排序,截取skn]
RecallResult recallResult = recallResultBuilder.builderRecallResult(recallResponseBatch, param, persionalFactor);
return recallResult;
}
}
... ...
package com.yoho.search.recall.scene;
package com.yoho.search.recall.scene.component;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.search.base.utils.CollectionUtils;
... ... @@ -21,7 +21,7 @@ import java.util.List;
import java.util.Map;
@Component
public class RecallCommonService {
public class BatchRecallComponent {
@Autowired
private SearchRedis searchRedis;
... ... @@ -31,13 +31,13 @@ public class RecallCommonService {
/**
* 批量召回入口
*
* @param requests
* @param batchRequests
* @return
*/
public List<RecallRequestResponse> batchRecallAndCache(final List<RecallRequest> requests) {
public List<RecallRequestResponse> batchRecallAndCache(final List<RecallRequest> batchRequests) {
//1、先从缓存中获取数据,并且构建返回结果对象
final List<RecallRequestResponse> results = this.queryResultFromCache(requests);
final List<RecallRequestResponse> results = this.queryResultFromCache(batchRequests);
//2、构造未命中缓存的请求-最多透传x个
final List<RecallRequest> notCachedRequests = this.buildNotCachedRequests(results, 10);
... ...
package com.yoho.search.recall.scene.component;
import com.yoho.search.recall.scene.models.RecallParams;
import com.yoho.search.recall.scene.models.RecallRequest;
import com.yoho.search.recall.scene.persional.PersionalFactor;
import com.yoho.search.recall.scene.request.BrandRecallRequestBuilder;
import com.yoho.search.recall.scene.request.CommonRecallRequestBuilder;
import com.yoho.search.recall.scene.request.SortPriceRecallRequestBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
public class BatchRequestsBuilder {
@Autowired
private CommonRecallRequestBuilder commonRequestBuilder;
@Autowired
private BrandRecallRequestBuilder brandRequestBuilder;
@Autowired
private SortPriceRecallRequestBuilder sortPriceRequestBuilder;
/**
* 批量请求构造器
* @param param
* @param persionalFactor
* @return
*/
public List<RecallRequest> buildBatchRequests(RecallParams param,PersionalFactor persionalFactor) {
//1、构造召回请求
List<RecallRequest> allRequests = new ArrayList<>();
//2、构造非个性化的请求
List<RecallRequest> commonRequests = commonRequestBuilder.buildCommonRecallRequests(param.getParamQueryFilter(), param.getFirstProductSkns(), param.getPageSize());
allRequests.addAll(commonRequests);
//4、构建个性化品牌的召回请求
List<RecallRequest> brandRequests = brandRequestBuilder.buildBrandRecallRequests(param.getParamQueryFilter(), persionalFactor.getBrandIds());
allRequests.addAll(brandRequests);
//5、构建个性化品牌的召回请求
List<RecallRequest> sortPriceRequests = sortPriceRequestBuilder.buildSortPriceRecallRequests(param.getParamQueryFilter(), persionalFactor.getSortPriceAreas());
allRequests.addAll(sortPriceRequests);
return allRequests;
}
}
... ...
package com.yoho.search.recall.scene.component;
import com.yoho.search.recall.scene.models.*;
import com.yoho.search.recall.scene.persional.PersionalFactor;
import com.yoho.search.recall.scene.strategy.StrategyNameEnum;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class BatchResponseBuilder {
/**
* 召回结果构造器
* @param requestResponses
* @return
*/
public RecallResponseBatch buildRecallResponseBatch(List<RecallRequestResponse> requestResponses){
//1、从兜底类型中获取总数
long total = this.getTotalCount(requestResponses);
//2、获取召回的skn
List<RecallResponseBatch.SknResult> sknResults = this.distinctRecallSkn(requestResponses);
//3、返回召回结果
return new RecallResponseBatch(total, sknResults);
}
/**
* 从兜底类型中获取总数
*
* @param requestResponses
* @return
*/
private long getTotalCount(List<RecallRequestResponse> requestResponses) {
long total = 0;
for (RecallRequestResponse requestResponse : requestResponses) {
RecallRequest request = requestResponse.getRequest();
RecallResponse response = requestResponse.getResponse();
if (request ==null || response == null) {
continue;
}
if (StrategyNameEnum.COMMON.name().equalsIgnoreCase(request.requestType())){
total = response.getTotal();
break;
}
}
return total;
}
/**
* 召回结果去重
*
* @param requestResponses
* @return
*/
private List<RecallResponseBatch.SknResult> distinctRecallSkn(List<RecallRequestResponse> requestResponses) {
List<RecallResponseBatch.SknResult> sknResults = new ArrayList<>();
Map<Integer,List<String>> sknRequestMaps = new HashMap<>();
for (RecallRequestResponse requestResponse : requestResponses) {
RecallRequest request = requestResponse.getRequest();
RecallResponse response = requestResponse.getResponse();
if (request==null || response == null || response.getSkns()==null){
continue;
}
for (RecallResponse.RecallSkn recallSkn : response.getSkns()) {
List<String> requestTypes = sknRequestMaps.get(recallSkn.getSkn());
if(requestTypes==null){
sknResults.add(new RecallResponseBatch.SknResult(recallSkn));
requestTypes = new ArrayList<>();
sknRequestMaps.put(recallSkn.getSkn(),requestTypes);
}
requestTypes.add(request.requestType());
}
}
for (RecallResponseBatch.SknResult sknResult:sknResults) {
sknResult.setRequestTypes(sknRequestMaps.get(sknResult.getProductSkn()));
}
return sknResults;
}
}
... ...
package com.yoho.search.recall.scene.component;
import com.yoho.search.recall.scene.models.ParamQueryFilter;
import com.yoho.search.recall.scene.models.RecallParams;
import com.yoho.search.recall.sort.helper.RecallServiceHelper;
import com.yoho.search.service.helper.SearchServiceHelper;
import org.apache.commons.collections.MapUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class RecallParamsBuilder {
@Autowired
private SearchServiceHelper searchServiceHelepr;
@Autowired
private RecallServiceHelper recallServiceHelper;
public RecallParams buildRecallParams(Map<String, String> paramMap) throws Exception {
//1、获取链接中的query和filter参数
QueryBuilder query = searchServiceHelepr.constructQueryBuilder(paramMap);
BoolQueryBuilder filter = searchServiceHelepr.constructFilterBuilder(paramMap, null);
ParamQueryFilter queryFilter = new ParamQueryFilter(query,filter);
//2、获取分页参数
int page = MapUtils.getIntValue(paramMap, "page", 1);
int pageSize = MapUtils.getIntValue(paramMap, "viewNum", 10);
//3、获取firstSkn参数
List<String> firstProductSkns = recallServiceHelper.getFirstProductSkns(paramMap);
//4、获取uid或udid
int uid = MapUtils.getIntValue(paramMap, "uid", 1);
String udid = MapUtils.getString(paramMap, "udid", "");
return new RecallParams(queryFilter,page,pageSize, firstProductSkns , uid, udid);
}
}
... ...
package com.yoho.search.recall.scene.component;
import com.yoho.search.recall.scene.models.RecallParams;
import com.yoho.search.recall.scene.models.RecallResponseBatch;
import com.yoho.search.recall.scene.models.RecallResult;
import com.yoho.search.recall.scene.persional.PersionalFactor;
import com.yoho.search.recall.scene.strategy.StrategyNameEnum;
import com.yoho.search.service.base.ProductListSortKey;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.helper.SearchCommonHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
@Component
public class RecallResultBuilder {
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private ProductListSortService productListSortService;
public RecallResult builderRecallResult(RecallResponseBatch recallResponseBatch, RecallParams param, PersionalFactor persionalFactor){
//1、构造结果中的分页信息
final long total = recallResponseBatch.getTotal();
final int page = param.getPage();
final int pageSize = param.getPageSize();
final long pageTotal = searchCommonHelper.getTotalPage(total,pageSize);
//2、获取召回结果中的最大整数页码
List<RecallResponseBatch.SknResult> sknResultList = recallResponseBatch.getSknList();
//3、计算得分
this.doCalScore(sknResultList,persionalFactor);
//4、排序
Collections.sort(sknResultList, new Comparator<RecallResponseBatch.SknResult>() {
@Override
public int compare(RecallResponseBatch.SknResult o1, RecallResponseBatch.SknResult o2) {
return o2.getScore().compareTo(o1.getScore());// 大的排前面
}
});
//5、品牌品类平衡
sknResultList = productListSortService.sortProductList(sknResultList, new ProductListSortKey<RecallResponseBatch.SknResult>() {
@Override
public String getSortKey(RecallResponseBatch.SknResult product) {
return new StringBuilder().append(product.getBrandId()).append("_").append(product.getMiddleSortId()).toString();
}
@Override
public int getMaxCount() {
return 2;
}
});
//6、处理直通车
//7、截取整数页
int recallMaxPage = (sknResultList.size() / pageSize);
if (recallMaxPage == 0) {
recallMaxPage = 1;
}
if (recallMaxPage > 5) {
recallMaxPage = 5;
}
//8、判断当前页码是否在召回结果中
int realPage = page;
List<Integer> sknList = new ArrayList<>();
if(page > recallMaxPage) {
realPage = page - recallMaxPage;
sknList = this.getSknList(sknResultList);
}else{
}
return new RecallResult(total,page,pageSize,pageTotal,realPage,sknList);
}
private void doCalScore(List<RecallResponseBatch.SknResult> sknResultList,PersionalFactor persionalFactor) {
String userFactor = persionalFactor.getUserFactor();
for (RecallResponseBatch.SknResult sknResult : sknResultList) {
if (sknResult.getRequestTypes().contains(StrategyNameEnum.FIRST_PRODUCT_SKN.name())) {
sknResult.setScore(10000d);// firstSkn排第一个
sknResult.setScore(Math.random());
} else {
sknResult.setScore(Math.random());
}
}
}
private List<Integer> getSknList(List<RecallResponseBatch.SknResult> sknResultList){
List<Integer> sknList = new ArrayList<>();
for (RecallResponseBatch.SknResult sknResult:sknResultList){
sknList.add(sknResult.getProductSkn());
}
return sknList;
}
}
... ...
package com.yoho.search.recall.scene.models;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import java.util.List;
public class RecallParams {
private ParamQueryFilter paramQueryFilter;
private List<String> firstProductSkns;
private int pageSize;
private int uid;
private String udid;
private final ParamQueryFilter paramQueryFilter;
private final int page;
private final int pageSize;
private final List<String> firstProductSkns;
private final int uid;
private final String udid;
public RecallParams(ParamQueryFilter paramQueryFilter, List<String> firstProductSkns, int pageSize, int uid, String udid) {
public RecallParams(ParamQueryFilter paramQueryFilter,int page, int pageSize,List<String> firstProductSkns, int uid, String udid) {
this.paramQueryFilter = paramQueryFilter;
this.firstProductSkns = firstProductSkns;
this.page = page;
this.pageSize = pageSize;
this.uid = uid;
this.udid = udid;
... ... @@ -25,8 +24,8 @@ public class RecallParams {
return paramQueryFilter;
}
public List<String> getFirstProductSkns() {
return firstProductSkns;
public int getPage() {
return page;
}
public int getPageSize() {
... ... @@ -41,4 +40,8 @@ public class RecallParams {
return udid;
}
public List<String> getFirstProductSkns() {
return firstProductSkns;
}
}
... ...
... ... @@ -7,7 +7,7 @@ public class RecallResponseBatch {
private long total;
private List<SknResult> sknList;
public RecallResponseBatch(long total, List<SknResult> sknList) {
public RecallResponseBatch(long total,List<SknResult> sknList) {
this.total = total;
this.sknList = sknList;
}
... ... @@ -26,6 +26,8 @@ public class RecallResponseBatch {
private Integer brandId;
private Integer middleSortId;
private List<String> requestTypes;
private String factor;
private Double score;
public SknResult(RecallResponse.RecallSkn recallSkn) {
this.productSkn = recallSkn.getSkn();
... ... @@ -52,6 +54,22 @@ public class RecallResponseBatch {
public void setRequestTypes(List<String> requestTypes) {
this.requestTypes = requestTypes;
}
public Double getScore() {
return score;
}
public void setScore(Double score) {
this.score = score;
}
public String getFactor() {
return factor;
}
public void setFactor(String factor) {
this.factor = factor;
}
}
}
... ...
package com.yoho.search.recall.scene.models;
import java.util.List;
public class RecallResult {
private final long total;
private final int page;
private final int pageSize;
private final long pageTotal;
private final int realPage;
private final List<Integer> sknList;
public RecallResult(long total,int page, int pageSize,long pageTotal, int realPage,List<Integer> sknList) {
this.total = total;
this.page = page;
this.pageSize = pageSize;
this.pageTotal = pageTotal;
this.realPage = realPage;
this.sknList = sknList;
}
public long getTotal() {
return total;
}
public int getPage() {
return page;
}
public int getPageSize() {
return pageSize;
}
public long getPageTotal() {
return pageTotal;
}
public int getRealPage() {
return realPage;
}
public List<Integer> getSknList() {
return sknList;
}
}
... ...
... ... @@ -9,13 +9,15 @@ public class PersionalFactor implements Serializable{
private List<Integer> brandIds;
private List<SortPriceArea> sortPriceAreas;
private String userFactor;
public PersionalFactor() {
}
public PersionalFactor(List<Integer> brandIds, List<SortPriceArea> sortPriceAreas) {
public PersionalFactor(List<Integer> brandIds, List<SortPriceArea> sortPriceAreas,String userFactor){
this.brandIds = brandIds;
this.sortPriceAreas = sortPriceAreas;
this.userFactor = userFactor;
}
public void setBrandIds(List<Integer> brandIds) {
... ... @@ -34,6 +36,14 @@ public class PersionalFactor implements Serializable{
return sortPriceAreas;
}
public String getUserFactor() {
return userFactor;
}
public void setUserFactor(String userFactor) {
this.userFactor = userFactor;
}
public static class SortPriceArea implements Serializable{
private static final long serialVersionUID = -7973209074997705083L;
... ...
... ... @@ -71,7 +71,7 @@ class PersionalFactorPageComponent {
Map<String, Aggregation> aggregationMap = searchResult.getAggMaps();
List<Integer> brandIds = this.getBrandIdsFromAggregationMap(aggregationMap);
List<PersionalFactor.SortPriceArea> sortPriceAreas = this.getSortPriceAreasFromAggregationMap(aggregationMap);
pagePersionalFactor = new PersionalFactor(brandIds, sortPriceAreas);
pagePersionalFactor = new PersionalFactor(brandIds, sortPriceAreas,null);
//6、加入缓存
searchCacheService.addSerializableObjectToCache(searchCacheFactory.getAggregationSearchCache(),cacheKey,pagePersionalFactor,true);
return pagePersionalFactor;
... ...
... ... @@ -24,7 +24,8 @@ class PersionalFactorUserComponent {
for (int i = 0; i < 50; i++) {
sortPriceArea.add(new PersionalFactor.SortPriceArea((int) (Math.random() * 1000), (int) (Math.random() * 3)));
}
return new PersionalFactor(brandIds, sortPriceArea);
String factor = "";
return new PersionalFactor(brandIds, sortPriceArea,factor);
}
... ...
package com.yoho.search.recall.scene.persional;
import com.yoho.search.recall.scene.models.ParamQueryFilter;
import com.yoho.search.recall.scene.models.RecallParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -22,20 +23,23 @@ public class RecallPersionalService {
/**
* 获取个性化因子
*
* @param paramQueryFilter
* @param udid
* @param recallParams
* @return
*/
public PersionalFactor queryPersionalFactor(ParamQueryFilter paramQueryFilter, int uid, String udid) {
//1、获取页面上的个性化因子
PersionalFactor pageFactor = pageComponent.queryPagePersionalFactor(paramQueryFilter);
//2、获取用户的个性化因子
PersionalFactor userFactor = userComponent.queryUserPersionalFactor(uid, udid);
//3、join获取最终的结果
List<Integer> brandIds = this.innerJoin(pageFactor.getBrandIds(),userFactor.getBrandIds(),10);
List<PersionalFactor.SortPriceArea> sortPriceAreas = this.innerJoin(pageFactor.getSortPriceAreas(),userFactor.getSortPriceAreas(),5);
//logger.info("getPersionalUseFactor,brandIds is[{}],sortPriceAreas is [{}]",brandIds,sortPriceAreas);
return new PersionalFactor(brandIds, sortPriceAreas);
public PersionalFactor queryPersionalFactor(RecallParams recallParams) {
try {
//1、获取页面上的个性化因子
PersionalFactor pageFactor = pageComponent.queryPagePersionalFactor(recallParams.getParamQueryFilter());
//2、获取用户的个性化因子
PersionalFactor userFactor = userComponent.queryUserPersionalFactor(recallParams.getUid(), recallParams.getUdid());
//3、join获取最终的结果
List<Integer> brandIds = this.innerJoin(pageFactor.getBrandIds(),userFactor.getBrandIds(),10);
List<PersionalFactor.SortPriceArea> sortPriceAreas = this.innerJoin(pageFactor.getSortPriceAreas(),userFactor.getSortPriceAreas(),5);
return new PersionalFactor(brandIds, sortPriceAreas,userFactor.getUserFactor());
}catch (Exception e){
logger.error(e.getMessage());
return new PersionalFactor(new ArrayList<>(),new ArrayList<>(),"");
}
}
private <T> List<T> innerJoin(List<T> aList,List<T> bList,int size) {
... ...
package com.yoho.search.recall.sort;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.yoho.search.service.helper.SearchCommonHelper;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.models.RecallType;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortKey;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.recall.sort.helper.RecallPersionalHelper;
import com.yoho.search.recall.sort.helper.RecallServiceHelper;
import com.yoho.search.recall.sort.model.RecallProductInfoList;
import com.yoho.search.recall.sort.model.RecallProductSknList;
import com.yoho.search.recall.sort.model.RecallResult;
import com.yoho.search.recall.sort.model.RecallSearchResult;
import com.yoho.search.recall.sort.model.UserLikeBrands;
import com.yoho.search.recall.sort.strategy.AddFlowStrategy;
import com.yoho.search.recall.sort.strategy.CommonStrategy;
import com.yoho.search.recall.sort.strategy.DirectTrainStrategy;
import com.yoho.search.recall.sort.strategy.FirstProductSknStrategy;
import com.yoho.search.recall.sort.strategy.IRecallStrategy;
import com.yoho.search.recall.sort.strategy.NewPromotionStrategy;
import com.yoho.search.recall.sort.strategy.NewReducePriceStrategy;
import com.yoho.search.recall.sort.strategy.NewShelveStrategy;
import com.yoho.search.recall.sort.strategy.NewShopStrategy;
import sun.applet.Main;
import com.yoho.search.recall.sort.model.*;
import com.yoho.search.recall.sort.strategy.*;
import com.yoho.search.service.base.ProductListSortKey;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.helper.SearchCommonHelper;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class SortRecallSceneService extends AbstractRecallService {
... ... @@ -164,9 +143,9 @@ public class SortRecallSceneService extends AbstractRecallService {
// 3、加入剩余商品
results.addAll(productList);
// 4、品牌打散
ProductListSortKey productSortKey = new ProductListSortKey() {
results = productListSortService.sortProductList(results, new ProductListSortKey<Map<String, Object>>() {
@Override
public String getSortKey(Map<?, ?> product) {
public String getSortKey(Map<String, Object> product) {
return MapUtils.getString(product, ProductIndexEsField.brandId, "0");
}
... ... @@ -174,8 +153,7 @@ public class SortRecallSceneService extends AbstractRecallService {
public int getMaxCount() {
return 2;
}
};
results = productListSortService.sortProductMapList(results, productSortKey);
});
// 5、回设productList
recallResult.setProductList(results);
return recallResult;
... ...
package com.yoho.search.service.base;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class FillProductListService {
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private ProductListSortService productListSortService;
public JSONObject queryProductListResult(SearchParam searchParam){
// 1)设置返回的参数【节省带宽】
List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
searchParam.setIncludeFields(includeFields);
// 2)查询
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
// 3)品牌品类打散
product_list = productListSortService.sortProductList(product_list, new ProductListSortKey<Map<String, Object>>() {
@Override
public String getSortKey(Map<String, Object> product) {
return MapUtils.getString(product, "brand_id", "0");
}
@Override
public int getMaxCount() {
return 2;
}
});
// 4)构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
dataMap.put("product_list", product_list);
return dataMap;
}
}
... ...