Authored by hugufei

Merge branch 'master' into couponlimit

Showing 28 changed files with 403 additions and 202 deletions
... ... @@ -20,7 +20,7 @@ public class CommonRecallRequestBuilder{
* @param firstProductSkns
* @return
*/
public List<RecallRequest> buildCommonRecallRequests(ParamQueryFilter paramQueryFilter, List<String> firstProductSkns) {
public List<RecallRequest> buildCommonRecallRequests(ParamQueryFilter paramQueryFilter,int pageSize, List<String> firstProductSkns) {
//1、构造召回请求
List<RecallRequest> requests = new ArrayList<>();
//1.1) firstSkn的召回
... ... @@ -28,7 +28,7 @@ public class CommonRecallRequestBuilder{
//1.2) 直通车召回
requests.add(this.buildDirectTrainRequest(paramQueryFilter, SknCountConstants.DIRECT_TRAIN_RECALL_COUNT));
//1.3) 人气的召回
requests.add(this.buildCommonRequest(paramQueryFilter,SknCountConstants.COMMON_HEAT_VALUE));
requests.add(this.buildCommonRequest(paramQueryFilter,Math.max(SknCountConstants.COMMON_HEAT_VALUE,pageSize)));
//1.4) 新开店铺的召回
requests.add(this.buildNewShopRequest(paramQueryFilter, SknCountConstants.NEW_SHOP));
//1.5) 流量补偿的召回
... ...
... ... @@ -2,6 +2,7 @@ package com.yoho.search.recall.scene.beans.builder;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.strategy.IStrategy;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.impls.*;
import com.yoho.search.recall.scene.constants.SknCountConstants;
import com.yoho.search.recall.scene.models.common.ParamQueryFilter;
... ... @@ -20,24 +21,24 @@ public class SortBrandRecallRequestBuilder {
* @param sortBrands
* @return
*/
public List<RecallRequest> buildSortBrandRecallRequests(ParamQueryFilter paramQueryFilter, List<SortBrand> sortBrands,boolean isForecast){
public List<RecallRequest> buildSortBrandRecallRequests(ParamQueryFilter paramQueryFilter, List<SortBrand> sortBrands,SortBrandType sortBrandType){
//1、构造召回请求
List<RecallRequest> requests = new ArrayList<>();
// 1) 人气
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandHeatValueRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,isForecast));
requests.add(this.buildSortBrandHeatValueRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,sortBrandType));
}
// 2) 新品
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandNewShelveRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,isForecast));
requests.add(this.buildSortBrandNewShelveRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,sortBrandType));
}
// 3) 新降价
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandReducePriceRequest(paramQueryFilter, sortBrand,SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,isForecast));
requests.add(this.buildSortBrandReducePriceRequest(paramQueryFilter, sortBrand,SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,sortBrandType));
}
// 4) 新开促销
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandPromotionRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,isForecast));
requests.add(this.buildSortBrandPromotionRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT,sortBrandType));
}
return requests;
}
... ... @@ -50,8 +51,8 @@ public class SortBrandRecallRequestBuilder {
* @param size
* @return
*/
private RecallRequest buildSortBrandHeatValueRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,boolean isForecast) {
IStrategy strategy = new SortBrandHeatValueStrategy(sortBrand, size,isForecast);
private RecallRequest buildSortBrandHeatValueRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,SortBrandType sortBrandType) {
IStrategy strategy = new SortBrandHeatValueStrategy(sortBrand, size,sortBrandType);
return new RecallRequest(paramQueryFilter, strategy);
}
... ... @@ -63,8 +64,8 @@ public class SortBrandRecallRequestBuilder {
* @param size
* @return
*/
private RecallRequest buildSortBrandNewShelveRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,boolean isForecast) {
IStrategy strategy = new SortBrandNewShelveStrategy(sortBrand, size, isForecast);
private RecallRequest buildSortBrandNewShelveRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,SortBrandType sortBrandType) {
IStrategy strategy = new SortBrandNewShelveStrategy(sortBrand, size, sortBrandType);
return new RecallRequest(paramQueryFilter, strategy);
}
... ... @@ -76,8 +77,8 @@ public class SortBrandRecallRequestBuilder {
* @param size
* @return
*/
private RecallRequest buildSortBrandReducePriceRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,boolean isForecast) {
IStrategy strategy = new SortBrandReducePriceStrategy(sortBrand, size,isForecast);
private RecallRequest buildSortBrandReducePriceRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,SortBrandType sortBrandType) {
IStrategy strategy = new SortBrandReducePriceStrategy(sortBrand, size,sortBrandType);
return new RecallRequest(paramQueryFilter, strategy);
}
... ... @@ -89,8 +90,8 @@ public class SortBrandRecallRequestBuilder {
* @param size
* @return
*/
private RecallRequest buildSortBrandPromotionRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,boolean isForecast) {
IStrategy strategy = new SortBrandPromotionStrategy(sortBrand, size,isForecast);
private RecallRequest buildSortBrandPromotionRequest(ParamQueryFilter paramQueryFilter, SortBrand sortBrand, int size,SortBrandType sortBrandType) {
IStrategy strategy = new SortBrandPromotionStrategy(sortBrand, size,sortBrandType);
return new RecallRequest(paramQueryFilter, strategy);
}
... ...
... ... @@ -220,7 +220,7 @@ public class UserRecallResponseBuilder {
@Override
public int getMaxCount() {
return 2;
return 4;
}
});
return results;
... ...
package com.yoho.search.recall.scene.beans.cache;
import com.alibaba.fastjson.JSON;
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.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.persional.QueryUserPersionalFactorBean;
import com.yoho.search.service.base.SearchCommonService;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@Component
public class SortBrandVectorCacheBean {
private static final Logger RECALL_NEW_LOGGER = LoggerFactory.getLogger("RECALL");
@Autowired
private SearchCommonService searchCommonService;
private ScheduledExecutorService schedule = Executors.newSingleThreadScheduledExecutor();
private Map<String, List<Double>> sortBrandVector;
@PostConstruct
void init() {
schedule.scheduleAtFixedRate(() -> sortBrandVector = loadAllSortBrandVectors(), 0, 3, TimeUnit.MINUTES);
}
public List<Double> queryBrandSortVector(SortBrand sortBrand) {
try {
if (sortBrandVector == null || sortBrandVector.isEmpty()) {
RECALL_NEW_LOGGER.warn("sortBrandVector is empty,please check........");
return new ArrayList<>();
}
return sortBrandVector.get(sortBrand.key());
} catch (Exception e) {
return new ArrayList<>();
}
}
private Map<String, List<Double>> loadAllSortBrandVectors() {
try {
RECALL_NEW_LOGGER.info("loadAllSortBrandVectors begin ........");
long begin = System.currentTimeMillis();
SearchParam searchParam = new SearchParam();
searchParam.setSize(20000);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_BIGDATASORTBRANDVECTOR, searchParam);
Map<String, List<Double>> result = new HashMap<>();
for (Map<String, Object> sortBrandVector : searchResult.getResultList()) {
try {
int middleSortId = MapUtils.getIntValue(sortBrandVector, "middleSortId", 0);
int brandId = MapUtils.getIntValue(sortBrandVector, "brandId", 0);
String vector = MapUtils.getString(sortBrandVector, "vector", "[]");
List<Double> vectorArray = JSON.parseArray(vector, Double.class);
if (middleSortId == 0 || brandId == 0 || vectorArray.isEmpty()) {
continue;
}
SortBrand sortBrand = new SortBrand(middleSortId, brandId);
result.put(sortBrand.key(), vectorArray);
} catch (Exception e) {
}
}
RECALL_NEW_LOGGER.info("loadAllSortBrandVectors end,size is[{}],cost is[{}]",result.size(),System.currentTimeMillis()-begin);
return result;
}catch (Exception e){
RECALL_NEW_LOGGER.error("loadAllSortBrandVectors fail"+e.getMessage(),e);
return null;
}
}
}
... ...
... ... @@ -6,6 +6,7 @@ import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.recall.scene.beans.builder.*;
import com.yoho.search.recall.scene.beans.persional.QueryUserPersionalFactorBean;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.impls.RecommendSknStrategy;
import com.yoho.search.recall.scene.models.common.RecallMergerResult;
import com.yoho.search.recall.scene.models.personal.UserPersonalFactor;
... ... @@ -111,15 +112,19 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
//3、处理实时推荐的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> realTimeSortBrandCompletableFuture = this.doRecallRealTimeSortBrand(userRecallRequest, userPersonalFactor);
//4、处理RNN预测的品类品牌的召回
//4、处理基于向量生成的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> vectorSortBrandCompletableFuture = this.doRecallVectorSortBrand(userRecallRequest, userPersonalFactor);
//5、处理RNN预测的品类品牌的召回
CompletableFuture<List<RecallRequestResponse>> forecastSortBrandCompletableFuture = this.doRecallForecastSortBrand(userRecallRequest, userPersonalFactor);
//5、构造最终返回结果投入额
//6、构造最终返回结果投入额
List<RecallRequestResponse> batchRequestResults = new ArrayList<>();
batchRequestResults.addAll(this.getResultFromCompletableFuture(recallBySknListCompletableFuture));//按skn召回放在第一个,不然merger的时候可能会无序
batchRequestResults.addAll(this.getResultFromCompletableFuture(commonCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(realTimeSortBrandCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(vectorSortBrandCompletableFuture));
batchRequestResults.addAll(this.getResultFromCompletableFuture(forecastSortBrandCompletableFuture));
//6、日志打印
... ... @@ -154,9 +159,9 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
private CompletableFuture<List<RecallRequestResponse>> doRecallCommon(UserRecallRequest userRecallRequest, UserPersonalFactor userPersonalFactor) {
return CompletableFuture.supplyAsync(() -> {
long begin = System.currentTimeMillis();
List<RecallRequest> commonRequests = commonRequestBuilder.buildCommonRecallRequests(userRecallRequest.getParamQueryFilter(), userRecallRequest.getFirstProductSkns());
List<RecallRequest> commonRequests = commonRequestBuilder.buildCommonRecallRequests(userRecallRequest.getParamQueryFilter(),userRecallRequest.getPageSize(), userRecallRequest.getFirstProductSkns());
List<RecallRequestResponse> commonRequestResponses = batchRecallCacheBean.batchRecallAndCache(commonRequests);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2]-doRecallCommon,requestCount is [{}], cost is [{}]", commonRequests.size(), System.currentTimeMillis() - begin);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2.1]-doRecallCommon,requestCount is [{}], cost is [{}]", commonRequests.size(), System.currentTimeMillis() - begin);
return commonRequestResponses;
}, recallExecutorService);
}
... ... @@ -173,8 +178,8 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
long begin = System.currentTimeMillis();
int recommendSknCount = userPersonalFactor.getRecommendSknList() == null ? 0 : userPersonalFactor.getRecommendSknList().size();
int realTimeSimilarSknCount = userPersonalFactor.getRealTimeSimilarSknList() == null ? 0 : userPersonalFactor.getRealTimeSimilarSknList().size();
List<RecallRequestResponse> recommendSknRequestResponses = sknRecallCacheBean.batchRecallBySknList(userRecallRequest,userPersonalFactor, 8);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2]-doRecallRecommendSkn,recommendSknCount is [{}],realTimeSimilarSknCount is[{}] ,cost is [{}]", recommendSknCount, realTimeSimilarSknCount,System.currentTimeMillis() - begin);
List<RecallRequestResponse> recommendSknRequestResponses = sknRecallCacheBean.batchRecallBySknList(userRecallRequest, userPersonalFactor, 8);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2.2]-doRecallRecommendSkn,recommendSknCount is [{}],realTimeSimilarSknCount is[{}] ,cost is [{}]", recommendSknCount, realTimeSimilarSknCount, System.currentTimeMillis() - begin);
return recommendSknRequestResponses;
}, recallExecutorService);
}
... ... @@ -189,14 +194,31 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
private CompletableFuture<List<RecallRequestResponse>> doRecallRealTimeSortBrand(UserRecallRequest userRecallRequest, UserPersonalFactor userPersonalFactor) {
return CompletableFuture.supplyAsync(() -> {
long begin = System.currentTimeMillis();
List<RecallRequest> realTimeSortBrandRequests = sortBrandRecallRequestBuilder.buildSortBrandRecallRequests(userRecallRequest.getParamQueryFilter(), userPersonalFactor.getRealTimeSortBrandList(), false);
List<RecallRequest> realTimeSortBrandRequests = sortBrandRecallRequestBuilder.buildSortBrandRecallRequests(userRecallRequest.getParamQueryFilter(), userPersonalFactor.getRealTimeSortBrandList(), SortBrandType.REC_SORT_BRAND);
List<RecallRequestResponse> realTimeSortBrandRequestResponses = batchRecallCacheBean.batchRecallAndCache(realTimeSortBrandRequests);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2]-doRecallRealTimeSortBrand,requestCount is [{}], cost is [{}]", realTimeSortBrandRequests.size(), System.currentTimeMillis() - begin);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2.3]-doRecallRealTimeSortBrand,requestCount is [{}], cost is [{}]", realTimeSortBrandRequests.size(), System.currentTimeMillis() - begin);
return realTimeSortBrandRequestResponses;
}, recallExecutorService);
}
/**
* 执行向量【品牌+品类】的召回
*
* @param userRecallRequest
* @param userPersonalFactor
* @return
*/
private CompletableFuture<List<RecallRequestResponse>> doRecallVectorSortBrand(UserRecallRequest userRecallRequest, UserPersonalFactor userPersonalFactor) {
return CompletableFuture.supplyAsync(() -> {
long begin = System.currentTimeMillis();
List<RecallRequest> vecortSortBrandRequests = sortBrandRecallRequestBuilder.buildSortBrandRecallRequests(userRecallRequest.getParamQueryFilter(), userPersonalFactor.getVectorSortBrandList(), SortBrandType.VEC_SORT_BRAND);
List<RecallRequestResponse> vecSortBrandRequestsResponses = batchRecallCacheBean.batchRecallAndCache(vecortSortBrandRequests);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2.4]-doRecallVectorSortBrand,requestCount is [{}], cost is [{}]", vecortSortBrandRequests.size(), System.currentTimeMillis() - begin);
return vecSortBrandRequestsResponses;
}, recallExecutorService);
}
/**
* 执行预测【品牌+品类】的召回
*
* @param userRecallRequest
... ... @@ -206,9 +228,9 @@ public class UserRecallCacheBean extends AbstractCacheBean<UserRecallRequest, Us
private CompletableFuture<List<RecallRequestResponse>> doRecallForecastSortBrand(UserRecallRequest userRecallRequest, UserPersonalFactor userPersonalFactor) {
return CompletableFuture.supplyAsync(() -> {
long begin = System.currentTimeMillis();
List<RecallRequest> forecastSortBrandRequests = sortBrandRecallRequestBuilder.buildSortBrandRecallRequests(userRecallRequest.getParamQueryFilter(), userPersonalFactor.getForecastSortBrandList(), true);
List<RecallRequest> forecastSortBrandRequests = sortBrandRecallRequestBuilder.buildSortBrandRecallRequests(userRecallRequest.getParamQueryFilter(), userPersonalFactor.getForecastSortBrandList(), SortBrandType.PRED_SORT_BRAND);
List<RecallRequestResponse> forecastSortBrandRequestsResponses = batchRecallCacheBean.batchRecallAndCache(forecastSortBrandRequests);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2]-doRecallForecastSortBrand,requestCount is [{}], cost is [{}]", forecastSortBrandRequests.size(), System.currentTimeMillis() - begin);
RECALL_NEW_LOGGER.info("UserRecallCacheBean[2.5]-doRecallForecastSortBrand,requestCount is [{}], cost is [{}]", forecastSortBrandRequests.size(), System.currentTimeMillis() - begin);
return forecastSortBrandRequestsResponses;
}, recallExecutorService);
}
... ...
... ... @@ -5,13 +5,12 @@ import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.constants.CacheTimeConstants;
import com.yoho.search.recall.scene.models.common.ParamQueryFilter;
import com.yoho.search.recall.scene.models.personal.PagePersonalFactor;
import com.yoho.search.recall.scene.models.personal.PageBrandSorts;
import com.yoho.search.service.base.SearchCommonService;
import org.apache.lucene.queryparser.xml.builders.BooleanQueryBuilder;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
... ... @@ -73,22 +72,20 @@ public class PagePersionalFactorComponent extends AbstractPageComponent<PagePers
//4、构造结果
Map<String, Aggregation> aggregationMap = searchResult.getAggMaps();
List<PageBrandSorts> sortBrands = this.getBrandSortsFromAggregationMap(aggregationMap);
List<SortBrand> sortBrands = this.getBrandSortsFromAggregationMap(aggregationMap);
List<Integer> misortIds = this.getMisortIds(sortBrands);
return new PagePersonalFactor(sortBrands,misortIds);
}
private List<Integer> getMisortIds(List<PageBrandSorts> sortBrands){
private List<Integer> getMisortIds(List<SortBrand> sortBrands){
if(sortBrands==null||sortBrands.isEmpty()){
return new ArrayList<>();
}
List<Integer> results = new ArrayList<>();
for (PageBrandSorts pageBrandSort : sortBrands) {
List<Integer> misortIds = pageBrandSort.getMisorts();
for(Integer misortid: misortIds){
if(!results.contains(misortid)){
results.add(misortid);
}
for (SortBrand sortBrand : sortBrands) {
Integer misort = sortBrand.getMisort();
if(!results.contains(misort)){
results.add(misort);
}
}
return results;
... ... @@ -101,17 +98,19 @@ public class PagePersionalFactorComponent extends AbstractPageComponent<PagePers
*/
private TermsAggregationBuilder brandSortAggBuilder() {
TermsAggregationBuilder middleSortAggBuilder = AggregationBuilders.terms("sortBrandBrandIdAgg").field(ProductIndexEsField.brandId).size(1000);
middleSortAggBuilder.subAggregation(AggregationBuilders.terms("sortBrandMiddleSortAgg").field(ProductIndexEsField.middleSortId).size(300));
middleSortAggBuilder.subAggregation(AggregationBuilders.terms("sortBrandMiddleSortAgg").field(ProductIndexEsField.middleSortId).size(200));
return middleSortAggBuilder;
}
private List<PageBrandSorts> getBrandSortsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
private List<SortBrand> getBrandSortsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
Map<Integer,List<Integer>> brand2MiSortIdsMap = this.getValueFromAggregationMap(aggregationMap,"sortBrandBrandIdAgg","sortBrandMiddleSortAgg");
List<PageBrandSorts> pageBrandSorts = new ArrayList<>();
List<SortBrand> pageBrandSorts = new ArrayList<>();
for (Map.Entry<Integer,List<Integer>> entry: brand2MiSortIdsMap.entrySet()) {
Integer brandId = entry.getKey();
List<Integer> misorts = entry.getValue();
pageBrandSorts.add(new PageBrandSorts(brandId,misorts));
for (Integer misort: misorts) {
pageBrandSorts.add(new SortBrand(misort,brandId));
}
}
return pageBrandSorts;
}
... ...
... ... @@ -59,8 +59,6 @@ public class PageProductIdBitSetComponent extends AbstractPageComponent<PageProd
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(paramQueryFilter.getParamFilter());
//filter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
//filter.mustNot(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
searchParam.setFiter(filter);
searchParam.setSize(0);
... ...
package com.yoho.search.recall.scene.beans.persional;
import com.alibaba.fastjson.JSON;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.core.personalized.models.SortPriceAreas;
import com.yoho.search.core.personalized.models.UserPersonalFactorRspNew;
import com.yoho.search.recall.scene.models.personal.PageBrandSorts;
import com.yoho.search.recall.scene.models.personal.PagePersonalFactor;
import com.yoho.search.recall.scene.models.personal.SortBrandVectorScore;
import com.yoho.search.recall.scene.models.personal.UserPersonalFactor;
import com.yoho.search.recall.scene.models.req.UserRecallRequest;
import com.yoho.search.service.base.SearchDynamicConfigService;
... ... @@ -30,6 +29,8 @@ public class QueryUserPersionalFactorBean {
private UserPersionalFactorComponent userComponent;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private SortBrandVectorComponent sortBrandVectorComponent;
/**
* 获取个性化因子
... ... @@ -51,7 +52,7 @@ public class QueryUserPersionalFactorBean {
long begin = System.currentTimeMillis();
PagePersonalFactor pageFactor = pageComponent.queryPagePersionalFactor(userRecallRequest.getParamQueryFilter());
long cost = System.currentTimeMillis() - begin;
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[1]:queryPageFactor. uid is[{}],udid is[{}], cost is[{}],size is[{}] ", uid, udid, cost, pageFactor == null ? "null" : pageFactor.pageBrandSortsSize());
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[1]:queryPageFactor. uid is[{}],udid is[{}], cost is[{}],size is[{}] ", uid, udid, cost, pageFactor == null ? "null" : pageFactor.sortBrandListSize());
//2、获取用户的个性化因子
begin = System.currentTimeMillis();
... ... @@ -63,14 +64,16 @@ public class QueryUserPersionalFactorBean {
if (!openDetailLog) {
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[2]:queryUserFactor. uid is[{}],udid is[{}], cost is[{}], forecastSortBrandSize is[{}],realTimeSortBrandSize is[{}], recommendSknSize is[{}] ", uid, udid, cost, forecastSortBrandSize, realTimeSortBrandSize, recommendSknSize);
} else {
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[2]:queryUserFactor. uid is[{}],udid is[{}], cost is[{}], forecastSortBrandSize is[{}],realTimeSortBrandSize is[{}], recommendSknSize is[{}],misortIds is[{}],userFactor is[{}] ", uid, udid, cost, forecastSortBrandSize, realTimeSortBrandSize, recommendSknSize, pageFactor.getMisortIds(),JSON.toJSONString(userFactor));
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[2]:queryUserFactor. uid is[{}],udid is[{}], cost is[{}], forecastSortBrandSize is[{}],realTimeSortBrandSize is[{}], recommendSknSize is[{}],misortIds is[{}],userFactor is[{}] ", uid, udid, cost, forecastSortBrandSize, realTimeSortBrandSize, recommendSknSize, pageFactor.getMisortIds(), JSON.toJSONString(userFactor));
}
//3、构造结果
begin = System.currentTimeMillis();
UserPersonalFactor userPersonalFactor = this.buildUserPersonalFactor(pageFactor, userFactor);
cost = System.currentTimeMillis() - begin;
if (!openDetailLog) {
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[3]:after join. uid is[{}],udid is[{}], forecastSortBrand size is[{}], realTimeSortBrand size is[{}], sortPriceAreas size is [{}] ", uid, udid, userPersonalFactor.getForecastSortBrandListSize(), userPersonalFactor.getRealTimeSortBrandListSize(), userPersonalFactor.getSortPriceAreasListSize());
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[3]:buildUserPersonalFactor.cost is[{}ms], uid is[{}],udid is[{}], forecastSortBrand size is[{}], realTimeSortBrand size is[{}], vectorSortBrand size is[{}], sortPriceAreas size is [{}] ",cost, uid, udid, userPersonalFactor.getForecastSortBrandListSize(), userPersonalFactor.getRealTimeSortBrandListSize(),userPersonalFactor.getVectorSortBrandListSize(), userPersonalFactor.getSortPriceAreasListSize());
} else {
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[3]:after join. uid is[{}],udid is[{}], forecastSortBrand size is[{}], realTimeSortBrand size is[{}], sortPriceAreas size is [{}], results is [{}] ", uid, udid, userPersonalFactor.getForecastSortBrandListSize(), userPersonalFactor.getRealTimeSortBrandListSize(), userPersonalFactor.getSortPriceAreasListSize(), JSON.toJSONString(userPersonalFactor));
RECALL_NEW_LOGGER.info("QueryUserPersionalFactorBean[3]:buildUserPersonalFactor.cost is[{}ms], uid is[{}],udid is[{}], forecastSortBrand size is[{}], realTimeSortBrand size is[{}], vectorSortBrand size is[{}], sortPriceAreas size is [{}], results is [{}] ",cost, uid, udid, userPersonalFactor.getForecastSortBrandListSize(), userPersonalFactor.getRealTimeSortBrandListSize(),userPersonalFactor.getVectorSortBrandListSize(), userPersonalFactor.getSortPriceAreasListSize(), JSON.toJSONString(userPersonalFactor));
}
return userPersonalFactor;
} catch (Exception e) {
... ... @@ -80,27 +83,40 @@ public class QueryUserPersionalFactorBean {
}
private UserPersonalFactor buildUserPersonalFactor(PagePersonalFactor pageFactor, UserPersonalFactorRspNew userFactor) {
//1、构造页面中的品牌品类map
Map<Integer, List<Integer>> pageBrand2MiSortIdsMap = this.getPageBrand2MiSortIdsMap(pageFactor);
//1、获取页面中存在的所有的key
Set<String> pageSortBrandKeys = new HashSet<>();
Set<String> filterSortBrandKeys = new HashSet<>();
for (SortBrand pageSortBrand : pageFactor.getSortBrandList()) {
pageSortBrandKeys.add(pageSortBrand.key());
}
//2、构造实时【品类+品牌】
int maxRealTimeSortBrandCount = searchDynamicConfigService.maxRealTimeSortBrandCount();
List<SortBrand> realTimeSortBrandList = this.getSortBrandListWithSort(null, pageBrand2MiSortIdsMap, userFactor.getRealTimeSortBrandList(), maxRealTimeSortBrandCount);
Set<String> realTimeSortBrandKeys = new HashSet<>();
for (SortBrand realTimeSortBrand : realTimeSortBrandList) {
realTimeSortBrandKeys.add(realTimeSortBrand.key());
List<SortBrand> realTimeSortBrandList = this.getSortBrandListWithSort(pageSortBrandKeys,filterSortBrandKeys,userFactor.getRealTimeSortBrandList(), maxRealTimeSortBrandCount);
for (SortBrand existSortBrand : realTimeSortBrandList) {
filterSortBrandKeys.add(existSortBrand.key());
}
//3、构造预测的【品牌+品牌】,去除实时的品类和品牌
//3、构造基于向量的【品牌+品牌】,去除实时的品类和品牌
int maxVectorSortBrandCount = searchDynamicConfigService.maxVectorSortBrandCount();
List<SortBrand> vectorSortBrandList = sortBrandVectorComponent.queryVectorSortBrandList(pageFactor.getSortBrandList(),filterSortBrandKeys,userFactor.getSortBrandVector(), maxVectorSortBrandCount);
for (SortBrand existSortBrand : vectorSortBrandList) {
filterSortBrandKeys.add(existSortBrand.key());
}
//4、构造预测的【品牌+品牌】,去除实时的品类和品牌
int maxForecastSortBrandCount = searchDynamicConfigService.maxForecastSortBrandCount();
int maxJoinSortBrandCount = searchDynamicConfigService.maxJoinSortBrandCount();
int count = Math.max(maxForecastSortBrandCount, maxJoinSortBrandCount - realTimeSortBrandList.size());
List<SortBrand> forecastSortBrandList = this.getSortBrandListWithSort(realTimeSortBrandKeys, pageBrand2MiSortIdsMap, userFactor.getSortBrandList(), count);
//4、构造品类价格带
List<SortBrand> forecastSortBrandList = this.getSortBrandListWithSort(pageSortBrandKeys,filterSortBrandKeys,userFactor.getSortBrandList(), maxForecastSortBrandCount);
for (SortBrand existSortBrand : forecastSortBrandList) {
filterSortBrandKeys.add(existSortBrand.key());
}
//5、构造品类价格带
List<SortPriceAreas> sortPriceAreasList = this.getSortPriceAreasListWithSort(userFactor, pageFactor);
//5、构造推荐的skn列表
//6、构造推荐的skn列表
List<Integer> recommendSknList = userFactor.getRecommendSknList();
List<Integer> realTimeSimilarSknList = this.queryRealTimeSimilarSknList(userFactor);
//6、返回最终结果
return new UserPersonalFactor(realTimeSortBrandList, forecastSortBrandList, sortPriceAreasList, recommendSknList, realTimeSimilarSknList, userFactor.getVector());
//7、返回最终结果
return new UserPersonalFactor(realTimeSortBrandList, forecastSortBrandList, vectorSortBrandList, sortPriceAreasList, recommendSknList, realTimeSimilarSknList, userFactor.getVector());
}
/**
... ... @@ -127,30 +143,13 @@ public class QueryUserPersionalFactorBean {
return results;
}
private Map<Integer, List<Integer>> getPageBrand2MiSortIdsMap(PagePersonalFactor pageFactor) {
if (pageFactor == null || pageFactor.getBrandSortsList() == null) {
return new HashMap<>();
}
//1、构造brand2MiSortIdsMap
List<PageBrandSorts> brandSortsList = pageFactor.getBrandSortsList();
Map<Integer, List<Integer>> brand2MiSortIdsMap = new HashMap<>();
for (PageBrandSorts pageBrandSorts : brandSortsList) {
brand2MiSortIdsMap.put(pageBrandSorts.getBrandId(), pageBrandSorts.getMisorts());
}
return brand2MiSortIdsMap;
}
private List<SortBrand> getSortBrandListWithSort(Set<String> filterSortBrandKeys, Map<Integer, List<Integer>> brand2MiSortIdsMap, List<SortBrand> userSortBrands, int maxCount) {
private List<SortBrand> getSortBrandListWithSort(Set<String> pageSortBrandKeys,Set<String> filterSortBrandKeys,List<SortBrand> userSortBrands, int maxCount) {
List<SortBrand> results = new ArrayList<>();
if (brand2MiSortIdsMap == null || brand2MiSortIdsMap.isEmpty() || userSortBrands == null || userSortBrands.isEmpty()) {
if (pageSortBrandKeys == null || pageSortBrandKeys.isEmpty() || userSortBrands == null || userSortBrands.isEmpty()) {
return results;
}
for (SortBrand sortBrand : userSortBrands) {
if (!brand2MiSortIdsMap.containsKey(sortBrand.getBrandId())) {
continue;
}
List<Integer> miSortIds = brand2MiSortIdsMap.get(sortBrand.getBrandId());
if (miSortIds == null || !miSortIds.contains(sortBrand.getMisort())) {
if (!pageSortBrandKeys.contains(sortBrand.key())) {
continue;
}
if (filterSortBrandKeys != null && filterSortBrandKeys.contains(sortBrand.key())) {
... ... @@ -164,6 +163,7 @@ public class QueryUserPersionalFactorBean {
return results;
}
/**
* 【品类+价格带】
*
... ...
package com.yoho.search.recall.scene.beans.persional;
import com.alibaba.fastjson.JSON;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.cache.SortBrandVectorCacheBean;
import com.yoho.search.recall.scene.models.personal.SortBrandVectorScore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
public class SortBrandVectorComponent {
@Autowired
private SortBrandVectorCacheBean sortBrandVectorCacheBean;
public List<SortBrand> queryVectorSortBrandList(List<SortBrand> pageSortBrands,Set<String> filterKeys, List<Double> userVectorList, int count){
List<SortBrandVectorScore> sortBrandVectorScores = new ArrayList<>();
for (SortBrand sortBrand:pageSortBrands) {
if(filterKeys.contains(sortBrand.key())){
continue;
}
List<Double> sortBrandVactor = sortBrandVectorCacheBean.queryBrandSortVector(sortBrand);
if(sortBrandVactor==null || sortBrandVactor.isEmpty()){
continue;
}
double score = this.calScore(sortBrandVactor,userVectorList);
sortBrandVectorScores.add(new SortBrandVectorScore(sortBrand,score));
}
Collections.sort(sortBrandVectorScores,(o1,o2)-> o2.getScore().compareTo(o1.getScore()));//得分高的排在前面
List<SortBrandVectorScore> sortBrandScoreList = CollectionUtils.safeSubList(sortBrandVectorScores,0,count);
List<SortBrand> result = new ArrayList<>();
for (SortBrandVectorScore sortBrandScore:sortBrandScoreList){
result.add(new SortBrand(sortBrandScore.getMisort(),sortBrandScore.getBrandId()));
}
return result;
}
private double calScore(List<Double> sortBrandVectorList, List<Double> userSortBrandVectorList){
if(sortBrandVectorList==null || userSortBrandVectorList==null ){
return Double.MIN_VALUE;
}
if(sortBrandVectorList.size()!=userSortBrandVectorList.size()){
return Double.MIN_VALUE;
}
double temp = 0;
for (int i=0;i<sortBrandVectorList.size();i++){
temp += sortBrandVectorList.get(i)*userSortBrandVectorList.get(i);
}
return Math.tanh(temp);
}
public static void main(String[] args) {
String x1 = "[-0.023208871483802795, -0.00123749696649611, -0.015170298516750336, -0.007396151311695576, -0.032640401273965836, -0.009461389854550362, -0.013294546864926815, -0.012132793664932251, -0.009638852439820766, 0.04573344811797142, -0.0028091748245060444, -0.04632924124598503, -0.02149336040019989, -0.027167582884430885, -0.008631616830825806, -0.010607016272842884, 0.004559996537864208, 0.016158537939190865, -0.009562269784510136, 0.02133280783891678]";
List<Double> xArray1 = JSON.parseArray(x1,Double.class);
String x2 = "[-0.02647276408970356, 0.046354155987501144, 0.04167942702770233, 0.036427706480026245, -0.017924591898918152, 0.04522036388516426, -0.03145822882652283, 0.043358903378248215, -0.009460432454943657, 0.02196604758501053, -0.03137994930148125, -0.016966382041573524, 0.03518626093864441, -0.034915290772914886, 0.030945859849452972, -0.03548983111977577, -0.005576461087912321, 0.03320769965648651, -0.01938728615641594, 0.005865586921572685]";
List<Double> xArray2 = JSON.parseArray(x2,Double.class);
System.out.println(new SortBrandVectorComponent().calScore(xArray1,xArray2));
}
}
... ...
... ... @@ -4,18 +4,12 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.search.core.personalized.models.*;
import com.yoho.search.recall.scene.models.personal.PageBrandSorts;
import com.yoho.search.recall.scene.models.personal.PagePersonalFactor;
import com.yoho.search.recall.scene.models.personal.PageSortPriceAreas;
import com.yoho.search.service.base.SearchDynamicConfigService;
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.Arrays;
import java.util.Collections;
import java.util.List;
@Component
... ...
package com.yoho.search.recall.scene.beans.strategy;
public enum SortBrandType {
REC_SORT_BRAND,
PRED_SORT_BRAND,
VEC_SORT_BRAND
}
... ...
... ... @@ -13,10 +13,15 @@ public enum StrategyEnum {
REC_S_B_PROMOTION(43),//实时的品牌+品类的新开促销
REC_S_B_NEW(44),//实时的品牌+品类的新品
PRED_S_B_HEAT_VALUE(31),//预测的品牌+品类的人气值
PRED_S_B_REDUCE_PRICE(32),//预测的品牌+品类的最新降价
PRED_S_B_PROMOTION(33),//预测的品牌+品类的新开促销
PRED_S_B_NEW(34),//预测的品牌+品类的新品
VEC_S_B_HEAT_VALUE(31),//向量预测的品牌+品类的人气值
VEC_S_B_REDUCE_PRICE(32),//向量预测的品牌+品类的最新降价
VEC_S_B_PROMOTION(33),//向量预测的品牌+品类的新开促销
VEC_S_B_NEW(34),//向量预测的品牌+品类的新品
PRED_S_B_HEAT_VALUE(21),//预测的品牌+品类的人气值
PRED_S_B_REDUCE_PRICE(22),//预测的品牌+品类的最新降价
PRED_S_B_PROMOTION(23),//预测的品牌+品类的新开促销
PRED_S_B_NEW(24),//预测的品牌+品类的新品
ADD_FLOW(12),//流量补偿
NEW_SHOP(11),//新开店铺
... ... @@ -34,11 +39,4 @@ public enum StrategyEnum {
return priority;
}
public static Integer getPriority(String name){
StrategyEnum strategyEnum = StrategyEnum.valueOf(name);
if(strategyEnum==null){
return 0;
}
return strategyEnum.priority;
}
}
... ...
... ... @@ -3,6 +3,7 @@ package com.yoho.search.recall.scene.beans.strategy.impls;
import com.alibaba.fastjson.JSON;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.strategy.IStrategy;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import com.yoho.search.recall.scene.constants.CacheTimeConstants;
... ... @@ -10,12 +11,12 @@ public abstract class SortBrandAbstractStrategy implements IStrategy {
protected SortBrand sortBrand;
protected int size;
protected boolean isForecast;
protected SortBrandType sortBrandType;
public SortBrandAbstractStrategy(SortBrand sortBrand, int size, boolean isForecast) {
public SortBrandAbstractStrategy(SortBrand sortBrand, int size, SortBrandType sortBrandType) {
this.sortBrand = sortBrand;
this.size = size;
this.isForecast=isForecast;
this.sortBrandType=sortBrandType;
}
@Override
... ... @@ -35,20 +36,57 @@ public abstract class SortBrandAbstractStrategy implements IStrategy {
return sb.toString();
}
public StrategyEnum heatValueStrategyEnum(){
return isForecast?StrategyEnum.PRED_S_B_HEAT_VALUE :StrategyEnum.REC_S_B_HEAT_VALUE;
public StrategyEnum heatValueStrategyEnum(SortBrandType sortBrandType){
switch (sortBrandType){
case REC_SORT_BRAND:
return StrategyEnum.REC_S_B_HEAT_VALUE;
case PRED_SORT_BRAND:
return StrategyEnum.PRED_S_B_HEAT_VALUE;
case VEC_SORT_BRAND:
return StrategyEnum.VEC_S_B_HEAT_VALUE;
default:
return null;
}
}
public StrategyEnum newStrategyEnum(){
return isForecast?StrategyEnum.PRED_S_B_NEW :StrategyEnum.REC_S_B_NEW;
public StrategyEnum newStrategyEnum(SortBrandType sortBrandType){
switch (sortBrandType){
case REC_SORT_BRAND:
return StrategyEnum.REC_S_B_NEW;
case PRED_SORT_BRAND:
return StrategyEnum.PRED_S_B_NEW;
case VEC_SORT_BRAND:
return StrategyEnum.VEC_S_B_NEW;
default:
return null;
}
}
public StrategyEnum promotionStrategyEnum(){
return isForecast?StrategyEnum.PRED_S_B_PROMOTION :StrategyEnum.REC_S_B_PROMOTION;
public StrategyEnum promotionStrategyEnum(SortBrandType sortBrandType){
switch (sortBrandType){
case REC_SORT_BRAND:
return StrategyEnum.REC_S_B_PROMOTION;
case PRED_SORT_BRAND:
return StrategyEnum.PRED_S_B_PROMOTION;
case VEC_SORT_BRAND:
return StrategyEnum.VEC_S_B_PROMOTION;
default:
return null;
}
}
public StrategyEnum reducePriceStrategyEnum(){
return isForecast?StrategyEnum.PRED_S_B_REDUCE_PRICE :StrategyEnum.REC_S_B_REDUCE_PRICE;
public StrategyEnum reducePriceStrategyEnum(SortBrandType sortBrandType){
switch (sortBrandType){
case REC_SORT_BRAND:
return StrategyEnum.REC_S_B_REDUCE_PRICE;
case PRED_SORT_BRAND:
return StrategyEnum.PRED_S_B_REDUCE_PRICE;
case VEC_SORT_BRAND:
return StrategyEnum.VEC_S_B_REDUCE_PRICE;
default:
return null;
}
}
}
... ...
... ... @@ -3,6 +3,7 @@ package com.yoho.search.recall.scene.beans.strategy.impls;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.beans.helper.SortBuilderHelper;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
... ... @@ -15,13 +16,13 @@ import org.elasticsearch.search.sort.SortBuilder;
*/
public class SortBrandHeatValueStrategy extends SortBrandAbstractStrategy {
public SortBrandHeatValueStrategy(SortBrand sortBrand, int size,boolean isForecast) {
super(sortBrand,size,isForecast);
public SortBrandHeatValueStrategy(SortBrand sortBrand, int size,SortBrandType sortBrandType) {
super(sortBrand,size,sortBrandType);
}
@Override
public StrategyEnum strategtEnum() {
return heatValueStrategyEnum();
return heatValueStrategyEnum(this.sortBrandType);
}
@Override
... ...
... ... @@ -3,6 +3,7 @@ package com.yoho.search.recall.scene.beans.strategy.impls;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.beans.helper.SortBuilderHelper;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
... ... @@ -15,13 +16,13 @@ import org.elasticsearch.search.sort.SortBuilder;
*/
public class SortBrandNewShelveStrategy extends SortBrandAbstractStrategy {
public SortBrandNewShelveStrategy(SortBrand sortBrand, int size,boolean isForecast) {
super(sortBrand,size,isForecast);
public SortBrandNewShelveStrategy(SortBrand sortBrand, int size,SortBrandType sortBrandType) {
super(sortBrand,size,sortBrandType);
}
@Override
public StrategyEnum strategtEnum() {
return newStrategyEnum();
return newStrategyEnum(this.sortBrandType);
}
@Override
... ...
... ... @@ -3,6 +3,7 @@ package com.yoho.search.recall.scene.beans.strategy.impls;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.beans.helper.SortBuilderHelper;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
... ... @@ -15,13 +16,13 @@ import org.elasticsearch.search.sort.SortBuilder;
*/
public class SortBrandPromotionStrategy extends SortBrandAbstractStrategy {
public SortBrandPromotionStrategy(SortBrand sortBrand, int size,boolean isForecast) {
super(sortBrand,size,isForecast);
public SortBrandPromotionStrategy(SortBrand sortBrand, int size,SortBrandType sortBrandType) {
super(sortBrand,size,sortBrandType);
}
@Override
public StrategyEnum strategtEnum() {
return promotionStrategyEnum();
return promotionStrategyEnum(this.sortBrandType);
}
@Override
... ...
... ... @@ -3,6 +3,7 @@ package com.yoho.search.recall.scene.beans.strategy.impls;
import com.yoho.search.core.personalized.models.SortBrand;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.beans.helper.SortBuilderHelper;
import com.yoho.search.recall.scene.beans.strategy.SortBrandType;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
... ... @@ -15,13 +16,13 @@ import org.elasticsearch.search.sort.SortBuilder;
*/
public class SortBrandReducePriceStrategy extends SortBrandAbstractStrategy {
public SortBrandReducePriceStrategy(SortBrand sortBrand, int size,boolean isForecast) {
super(sortBrand,size,isForecast);
public SortBrandReducePriceStrategy(SortBrand sortBrand, int size,SortBrandType sortBrandType) {
super(sortBrand,size,sortBrandType);
}
@Override
public StrategyEnum strategtEnum() {
return reducePriceStrategyEnum();
return reducePriceStrategyEnum(this.sortBrandType);
}
@Override
... ...
... ... @@ -2,10 +2,10 @@ package com.yoho.search.recall.scene.constants;
public class RecallCommonConstants {
public static final int maxRealTimeSortBrandCount = 20;//截取【品牌-品类】的数量-for排序
public static final int maxRealTimeSortBrandCount = 10;//截取【品牌-品类】的数量-for召回
public static final int maxForecastSortBrandCount = 20;//截取【品牌-品类】的数量-for排序
public static final int maxVectorSortBrandCount = 10;//截取【品牌-品类】的数量-for召回
public static final int maxJoinSortBrandCount = 20;//截取【品牌-品类】的数量-for排序
public static final int maxForecastSortBrandCount = 10;//截取【品牌-品类】的数量-for召回
}
... ...
... ... @@ -5,16 +5,15 @@ public class SknCountConstants {
/**
* 单次召回的商品数量
*/
public static final int COMMON_HEAT_VALUE = 60;
public static final int COMMON_HEAT_VALUE = 20;
public static final int FIRST_SKN = 1;
public static final int DIRECT_TRAIN_RECALL_COUNT = 100;
public static final int DIRECT_TRAIN_RETURN_COUNT = 20;
public static final int NEW_SHOP = 10;
public static final int ADD_FLOW = 10;
public static final int SORT_BRAND_RECALL_STRATEGY_SKN_COUNT = 4;
public static final int SORT_BRAND_RECALL_STRATEGY_SKN_COUNT = 8;
public static final int MAX_USER_RECALL_SKN_CACHE_COUNT = 100;
... ...
package com.yoho.search.recall.scene.models.personal;
import java.io.Serializable;
import java.util.List;
public class PageBrandSorts implements Serializable {
private static final long serialVersionUID = 6155493513881738094L;
private Integer brandId;
private List<Integer> misorts;
public PageBrandSorts() {
}
public PageBrandSorts(Integer brandId, List<Integer> misorts) {
this.brandId = brandId;
this.misorts = misorts;
}
public Integer getBrandId() {
return brandId;
}
public void setBrandId(Integer brandId) {
this.brandId = brandId;
}
public List<Integer> getMisorts() {
return misorts;
}
public void setMisorts(List<Integer> misorts) {
this.misorts = misorts;
}
}
package com.yoho.search.recall.scene.models.personal;
import com.yoho.search.core.personalized.models.SortBrand;
import java.io.Serializable;
import java.util.List;
/**
* 个性化因子参数
*/
public class PagePersonalFactor implements Serializable{
public class PagePersonalFactor implements Serializable {
private static final long serialVersionUID = 89030356435559223L;
private List<Integer> misortIds;
private List<PageBrandSorts> brandSortsList;
private List<SortBrand> sortBrandList;
public PagePersonalFactor() {
}
public PagePersonalFactor(List<PageBrandSorts> brandSortsList,List<Integer> misortIds){
this.brandSortsList = brandSortsList;
public PagePersonalFactor(List<SortBrand> sortBrandList, List<Integer> misortIds) {
this.sortBrandList = sortBrandList;
this.misortIds = misortIds;
}
public List<PageBrandSorts> getBrandSortsList() {
return brandSortsList;
}
public void setBrandSortsList(List<PageBrandSorts> brandSortsList) {
this.brandSortsList = brandSortsList;
public List<SortBrand> getSortBrandList() {
return sortBrandList;
}
public int pageBrandSortsSize(){
return brandSortsList==null ? 0:brandSortsList.size();
public void setSortBrandList(List<SortBrand> sortBrandList) {
this.sortBrandList = sortBrandList;
}
public List<Integer> getMisortIds() {
... ... @@ -40,4 +38,9 @@ public class PagePersonalFactor implements Serializable{
public void setMisortIds(List<Integer> misortIds) {
this.misortIds = misortIds;
}
public int sortBrandListSize() {
return sortBrandList==null?0:sortBrandList.size();
}
}
... ...
package com.yoho.search.recall.scene.models.personal;
import com.yoho.search.core.personalized.models.SortBrand;
public class SortBrandVectorScore extends SortBrand{
private static final long serialVersionUID = -4249350052442993709L;
private Double score;
public SortBrandVectorScore(SortBrand sortBrand,double score){
this.setBrandId(sortBrand.getBrandId());
this.setMisort(sortBrand.getMisort());
this.score = score;
}
public Double getScore() {
return score;
}
}
... ...
... ... @@ -10,6 +10,7 @@ public class UserPersonalFactor {
private List<SortBrand> realTimeSortBrandList;
private List<SortBrand> forecastSortBrandList;
private List<SortBrand> vectorSortBrandList;
private List<SortPriceAreas> sortPriceAreasList;
private List<Integer> recommendSknList;
private List<Integer> realTimeSimilarSknList;
... ... @@ -18,15 +19,17 @@ public class UserPersonalFactor {
public UserPersonalFactor (){
this.realTimeSortBrandList = new ArrayList<>();
this.forecastSortBrandList = new ArrayList<>();
this.vectorSortBrandList = new ArrayList<>();
this.sortPriceAreasList = new ArrayList<>();
this.recommendSknList = new ArrayList<>();
this.realTimeSimilarSknList = realTimeSimilarSknList;
this.realTimeSimilarSknList = new ArrayList<>();
this.vector = "";
}
public UserPersonalFactor(List<SortBrand> realTimeSortBrandList,List<SortBrand> forecastSortBrandList,List<SortPriceAreas> sortPriceAreasList,List<Integer> recommendSknList,List<Integer> realTimeSimilarSknList, String vector) {
public UserPersonalFactor(List<SortBrand> realTimeSortBrandList,List<SortBrand> forecastSortBrandList,List<SortBrand> vectorSortBrandList,List<SortPriceAreas> sortPriceAreasList,List<Integer> recommendSknList,List<Integer> realTimeSimilarSknList, String vector) {
this.realTimeSortBrandList = realTimeSortBrandList;
this.forecastSortBrandList = forecastSortBrandList;
this.vectorSortBrandList = vectorSortBrandList;
this.sortPriceAreasList = sortPriceAreasList;
this.recommendSknList = recommendSknList;
this.realTimeSimilarSknList = realTimeSimilarSknList;
... ... @@ -41,6 +44,10 @@ public class UserPersonalFactor {
return forecastSortBrandList;
}
public List<SortBrand> getVectorSortBrandList() {
return vectorSortBrandList;
}
public List<SortPriceAreas> getSortPriceAreasList() {
return sortPriceAreasList;
}
... ... @@ -61,6 +68,10 @@ public class UserPersonalFactor {
return forecastSortBrandList==null?0:forecastSortBrandList.size();
}
public int getVectorSortBrandListSize(){
return vectorSortBrandList==null?0:vectorSortBrandList.size();
}
public int getSortPriceAreasListSize(){
return sortPriceAreasList==null?0:sortPriceAreasList.size();
}
... ... @@ -68,4 +79,6 @@ public class UserPersonalFactor {
public List<Integer> getRealTimeSimilarSknList() {
return realTimeSimilarSknList;
}
}
... ...
... ... @@ -10,10 +10,9 @@ public class RecallRequestResponse extends AbstractCacheRequestResponse<RecallRe
super(request);
}
public RecallRequestResponse(RecallRequest request,RecallResponse recallResponse) {
super(request);
super.setResponse(recallResponse,false);
}
public static Transfer<String,RecallResponse> toResponseTransfer = (jsonValue)-> JSON.parseObject(jsonValue, RecallResponse.class);
public static Transfer<RecallResponse,String> fromResponseTransfer =(recallResponse)-> JSON.toJSONString(recallResponse);
@Override
public Transfer<String, RecallResponse> getToResponseTransfer() {
... ... @@ -25,17 +24,4 @@ public class RecallRequestResponse extends AbstractCacheRequestResponse<RecallRe
return fromResponseTransfer;
}
public static Transfer<String,RecallResponse> toResponseTransfer = new Transfer<String, RecallResponse>() {
@Override
public RecallResponse transfer(String jsonValue) {
return JSON.parseObject(jsonValue, RecallResponse.class);
}
};
public static Transfer<RecallResponse,String> fromResponseTransfer = new Transfer<RecallResponse, String>() {
@Override
public String transfer(RecallResponse recallResponse) {
return JSON.toJSONString(recallResponse);
}
};
}
... ...
... ... @@ -154,7 +154,7 @@ public class SearchDynamicConfigService {
* @return
*/
public boolean searchPersionalNewStrategyCommonJoinScoreOpen() {
return configReader.getBoolean("search.persional.newstrategy.common.join_score.open", true);
return configReader.getBoolean("search.persional.newstrategy.common.join_score.open", false);
}
/**
... ... @@ -167,21 +167,21 @@ public class SearchDynamicConfigService {
}
/**
* 新的的召回策略-预测的品牌品类
* 新的的召回策略-基于向量的品牌品类
*
* @return
*/
public int maxForecastSortBrandCount() {
return configReader.getInt("search.persional.newstrategy.forecast.max_sort_brand.count", RecallCommonConstants.maxForecastSortBrandCount);
public int maxVectorSortBrandCount() {
return configReader.getInt("search.persional.newstrategy.vector.max_sort_brand.count", RecallCommonConstants.maxVectorSortBrandCount);
}
/**
* 新的的召回策略-最多预测的品牌品类
* 新的的召回策略-预测的品牌品类
*
* @return
*/
public int maxJoinSortBrandCount() {
return configReader.getInt("search.persional.newstrategy.max_join_sort_brand.count", RecallCommonConstants.maxJoinSortBrandCount);
public int maxForecastSortBrandCount() {
return configReader.getInt("search.persional.newstrategy.forecast.max_sort_brand.count", RecallCommonConstants.maxForecastSortBrandCount);
}
/**
... ...
... ... @@ -3,7 +3,7 @@ search.es.cluster.name=yohosearch_test
search.es.servers=192.168.102.209:9300 192.168.102.216:9300
#search
search.minimum.should.match=3<90%
search.minimum.should.match=4<90%
search.operator=or
search.multiMatchQuery.type=CROSS_FIELDS
... ...
... ... @@ -56,6 +56,7 @@ search.persional.newstrategy.promotion.open=true
search.persional.newstrategy.first_page_cache.open=false
search.persional.newstrategy.common.join_score.open=true
search.persional.newstrategy.forecast.max_sort_brand.count=20
search.persional.newstrategy.vector.max_sort_brand.count=20
search.persional.newstrategy.realtime.max_sort_brand.count=20
search.persional.newstrategy.max_join_sort_brand.count=20
search.persional.newstrategy.directtrain.index.interval=4
... ...
... ... @@ -3,7 +3,7 @@ search.es.cluster.name=${search.es.cluster.name}
search.es.servers=${search.es.servers}
#search
search.minimum.should.match=3<90%
search.minimum.should.match=4<90%
search.operator=or
search.multiMatchQuery.type=CROSS_FIELDS
... ...