Authored by hugufei

兜底召回优化

... ... @@ -27,12 +27,16 @@ public class CommonRecallRequestBuilder{
requests.add(this.buildFirstSknRequest(paramQueryFilter, firstProductSkns, SknCountConstants.FIRST_SKN));
//1.2) 直通车召回
requests.add(this.buildDirectTrainRequest(paramQueryFilter, SknCountConstants.DIRECT_TRAIN_RECALL_COUNT));
//1.3) 人气的召回
requests.add(this.buildCommonRequest(paramQueryFilter,Math.max(SknCountConstants.COMMON_HEAT_VALUE,pageSize)));
//1.4) 新开店铺的召回
//1.3) 新开店铺的召回
requests.add(this.buildNewShopRequest(paramQueryFilter, SknCountConstants.NEW_SHOP));
//1.5) 流量补偿的召回
//1.4) 流量补偿的召回
requests.add(this.buildAddFlowRequest(paramQueryFilter, SknCountConstants.ADD_FLOW));
//1.5) 兜底的召回
requests.add(this.buildCommonRequest(paramQueryFilter,pageSize));
//1.6) 页面人气的召回
requests.add(this.buildCommonHeatValueRequest(paramQueryFilter,SknCountConstants.COMMON_HEAT_VALUE));
//1.7) 页面点击率的召回
requests.add(this.buildCommonCtrValueRequest(paramQueryFilter,SknCountConstants.COMMON_CTR_VALUE));
return requests;
}
... ... @@ -44,11 +48,35 @@ public class CommonRecallRequestBuilder{
* @return
*/
private RecallRequest buildCommonRequest(ParamQueryFilter paramQueryFilter, int size) {
CommonStrategy strategy = new CommonStrategy(size);
return new RecallRequest(paramQueryFilter, strategy);
}
/**
* 构建【按兜底召回】的请求参数
*
* @param paramQueryFilter
* @param size
* @return
*/
private RecallRequest buildCommonHeatValueRequest(ParamQueryFilter paramQueryFilter, int size) {
CommonHeatValueStrategy strategy = new CommonHeatValueStrategy(size);
return new RecallRequest(paramQueryFilter, strategy);
}
/**
* 构建【按兜底召回】的请求参数
*
* @param paramQueryFilter
* @param size
* @return
*/
private RecallRequest buildCommonCtrValueRequest(ParamQueryFilter paramQueryFilter, int size) {
CommonCtrValueStrategy strategy = new CommonCtrValueStrategy(size);
return new RecallRequest(paramQueryFilter, strategy);
}
/**
* 构造【按FIRST_SKN召回】的请求参数
*
* @param paramQueryFilter
... ...
... ... @@ -47,32 +47,12 @@ public class SortBrandRecallRequestBuilder {
requests.add(this.buildSortBrandPromotionRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT, sortBrandType));
}
// 5) 转化率-做AB
doSortBrandCtrValueABtest(requests, uid, paramQueryFilter, sortBrands, sortBrandType);
return requests;
}
private void doSortBrandCtrValueABtest(List<RecallRequest> requests, int uid, ParamQueryFilter paramQueryFilter, List<SortBrand> sortBrands, SortBrandType sortBrandType) {
if (uid % 2 == 1) {
if (searchDynamicConfigService.isAStrategyOpen()) {
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandCtrValueRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT, sortBrandType));
}
} else {
//do nothing
}
}
if (uid % 2 == 0) {
if (searchDynamicConfigService.isBStrategyOpen()) {
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandCtrValueRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT, sortBrandType));
}
} else {
//do nothing
}
for (SortBrand sortBrand : sortBrands) {
requests.add(this.buildSortBrandCtrValueRequest(paramQueryFilter, sortBrand, SknCountConstants.SORT_BRAND_RECALL_STRATEGY_SKN_COUNT, sortBrandType));
}
return requests;
}
/**
* 【按品类+品牌召回人气商品】
*
... ...
... ... @@ -33,8 +33,6 @@ public class UserRecallResponseBuilder {
private static final Logger RECALL_NEW_LOGGER = LoggerFactory.getLogger("RECALL");
@Autowired
private ProductListSortService productListSortService;
@Autowired
private PersonalVectorFeatureSearch personalVectorFeatureSearch;
@Autowired
private ProductFeatureFactorHepler productFeatureFactorHepler;
... ... @@ -55,25 +53,19 @@ public class UserRecallResponseBuilder {
sknResultList = this.fillBaseInfo(sknResultList);
//4、填充是否满足品类价格带的过滤
sknResultList = this.fillIsLikePriceArea(userRecallRequest.getUid(),sknResultList, userPersonalFactor);
sknResultList = this.fillIsLikePriceArea(userRecallRequest.getUid(), sknResultList, userPersonalFactor);
//5、按相关性计算得分
sknResultList = this.doCalScoreAndSort(sknResultList, userRecallRequest.getUid());
//6、品牌品类平衡
if (searchDynamicConfigService.searchPersionalNewStrategySortBrandBalance()) {
sknResultList = this.doBalance(sknResultList);
}
sknResultList = this.doCalScoreAndSort(sknResultList, userRecallRequest.getUid(), userRecallRequest.getPageSize());
//7、处理firstSkn-直通车等信息
//6、处理firstSkn-直通车等信息
sknResultList = this.doReRank(sknResultList);
//8、添加日志
//7、添加日志
for (RecallMergerResult.SknResult sknResult : sknResultList) {
this.logSknStrategyAndScore(userRecallRequest, sknResult);
}
//9、分页处理
//8、分页处理
int pageSize = userRecallRequest.getPageSize();
int recallTotalPage = (sknResultList.size() / pageSize);
if (recallTotalPage == 0) {
... ... @@ -82,7 +74,7 @@ public class UserRecallResponseBuilder {
recallTotalPage = Math.min(recallTotalPage, SknCountConstants.MAX_USER_RECALL_SKN_CACHE_COUNT / pageSize);//为用户最多保留X个skn进缓存
sknResultList = CollectionUtils.safeSubList(sknResultList, 0, recallTotalPage * pageSize);
//10、构造返回结果
//9、构造返回结果
List<RecallSknInfo> sknList = new ArrayList<>();
for (RecallMergerResult.SknResult sknResult : sknResultList) {
sknList.add(new RecallSknInfo(sknResult.getProductSkn(), sknResult.getStrategy().name()));
... ... @@ -145,50 +137,50 @@ public class UserRecallResponseBuilder {
for (RecallMergerResult.SknResult sknResult : sknResults) {
Integer misortId = sknResult.getMiddleSortId();
List<Integer> userPriceAreas = userMisort2PriceAreasMap.getOrDefault(misortId, new ArrayList<>());
boolean isLikePriceArea = this.isLikePriceArea(userPriceAreas,sknResult.getPriceArea());
boolean isLikePriceArea = this.isLikePriceArea(userPriceAreas, sknResult.getPriceArea());
sknResult.setLikePriceArea(isLikePriceArea);
}
return sknResults;
}
/**
*
* @param userPriceAreas
* @param sknPriceArea
* @return
*/
private boolean isLikePriceArea(List<Integer> userPriceAreas,Integer sknPriceArea){
private boolean isLikePriceArea(List<Integer> userPriceAreas, Integer sknPriceArea) {
try {
if(userPriceAreas==null || userPriceAreas.isEmpty()){
if (userPriceAreas == null || userPriceAreas.isEmpty()) {
return false;
}
return userPriceAreas.contains(sknPriceArea);
}catch (Exception e){
RECALL_NEW_LOGGER.error(e.getMessage(),e);
} catch (Exception e) {
RECALL_NEW_LOGGER.error(e.getMessage(), e);
return false;
}
}
/**
* 价格带左右各扩展一位
*
* @param userPriceAreas
* @param sknPriceArea
* @return
*/
private boolean isLikePriceAreaWithBStrategy(List<Integer> userPriceAreas,Integer sknPriceArea){
private boolean isLikePriceAreaWithBStrategy(List<Integer> userPriceAreas, Integer sknPriceArea) {
Collections.sort(userPriceAreas);
int min = userPriceAreas.get(0);
int max = userPriceAreas.get(userPriceAreas.size()-1);
int leftCount = min<=1 ? 0 : max>=7 ? 2 : 1;
int rightCount = min<=1 ? 2 : max>=7 ? 0 : 1;
for(int i = 1;i<=leftCount;i++){
if(min-i>=1){
userPriceAreas.add(0,min-i);
int max = userPriceAreas.get(userPriceAreas.size() - 1);
int leftCount = min <= 1 ? 0 : max >= 7 ? 2 : 1;
int rightCount = min <= 1 ? 2 : max >= 7 ? 0 : 1;
for (int i = 1; i <= leftCount; i++) {
if (min - i >= 1) {
userPriceAreas.add(0, min - i);
}
}
for(int i = 1;i<=rightCount;i++){
if(max+i<=7){
userPriceAreas.add(max+i);
for (int i = 1; i <= rightCount; i++) {
if (max + i <= 7) {
userPriceAreas.add(max + i);
}
}
return userPriceAreas.contains(sknPriceArea);
... ... @@ -200,7 +192,7 @@ public class UserRecallResponseBuilder {
* @param sknResultList
* @param uid
*/
private List<RecallMergerResult.SknResult> doCalScoreAndSort(List<RecallMergerResult.SknResult> sknResultList, int uid) {
private List<RecallMergerResult.SknResult> doCalScoreAndSort(List<RecallMergerResult.SknResult> sknResultList, int uid, int pageSize) {
//1、获取用户向量
Map<String, String> paramMap = new HashMap<>();
paramMap.put("uid", "" + uid);
... ... @@ -217,52 +209,61 @@ public class UserRecallResponseBuilder {
continue;
}
//2)如果是推荐出来的,则单独加分[以减分的方式依次保证顺序]
if (strategy.equals(StrategyEnum.REC_SKN)||strategy.equals(StrategyEnum.RT_SIM_SKN)) {
if (strategy.equals(StrategyEnum.REC_SKN) || strategy.equals(StrategyEnum.RT_SIM_SKN)) {
sknResult.setScore((double) recommendSknIndex--);
continue;
}
//3)向量计算
score = productFeatureFactorHepler.calProductFeatureFactor(userFeatureFactor, sknResult.getFactor());
//4)如果是直通车商品,则拿人气和向量综合评分
if (strategy.equals(StrategyEnum.DIRECT_TRAIN)) {
score = score * sknResult.getHeatValue();
}
//5)如果满足品类价格带偏好,则加分
if (sknResult.isLikePriceArea()) {
//5)如果当前skn不是兜底召回的,则加分【将兜底和非兜底的拆分】
if (!this.isCommonStrategy(strategy)) {
score = score + 1000;
}
//6)如果兜底策略不参与评分,并且当前skn不是兜底召回的,则加分【将兜底和非兜底的拆分】
if (!searchDynamicConfigService.searchPersionalNewStrategyCommonJoinScoreOpen() && !strategy.equals(StrategyEnum.COMMON)) {
//6)如果满足品类价格带偏好,则加分
if (sknResult.isLikePriceArea()) {
score = score + 500;
}
sknResult.setScore(score);
}
//3、按得分排序-得分高的在前面
//3、兜底数据处理
Iterator<RecallMergerResult.SknResult> iterator = sknResultList.iterator();
List<RecallMergerResult.SknResult> commonResultList = new ArrayList<>();
List<RecallMergerResult.SknResult> commonHeatValueResultList = new ArrayList<>();
List<RecallMergerResult.SknResult> commonCtrValueResultList = new ArrayList<>();
while (iterator.hasNext()) {
RecallMergerResult.SknResult sknResult = iterator.next();
if (sknResult.equals(StrategyEnum.COMMON)) {
commonResultList.add(sknResult);
iterator.remove();
}
if (sknResult.equals(StrategyEnum.COMMON_HEAT_VALUE)) {
commonHeatValueResultList.add(sknResult);
iterator.remove();
}
if (sknResult.equals(StrategyEnum.COMMON_CTR_VALUE)) {
commonCtrValueResultList.add(sknResult);
iterator.remove();
}
}
commonHeatValueResultList = CollectionUtils.safeSubList(commonHeatValueResultList, 0, pageSize);
commonCtrValueResultList = CollectionUtils.safeSubList(commonCtrValueResultList, 0, pageSize);
sknResultList.addAll(commonHeatValueResultList);
sknResultList.addAll(commonCtrValueResultList);
//3.1:如果是数量少于一页,则加会兜底的数据
if (sknResultList.size() < pageSize) {
sknResultList.addAll(commonResultList);
}
//4、按得分排序
Collections.sort(sknResultList, (o1, o2) -> o2.getScore().compareTo(o1.getScore()));
return sknResultList;
}
/**
* 精排-品类品牌平衡
*
* @param sknResultList
*/
private List<RecallMergerResult.SknResult> doBalance(List<RecallMergerResult.SknResult> sknResultList) {
List<RecallMergerResult.SknResult> results = productListSortService.sortProductList(sknResultList, new ProductListSortKey<RecallMergerResult.SknResult>() {
@Override
public String getSortKey(RecallMergerResult.SknResult product) {
return new StringBuilder().append(product.getBrandId()).append("_").append(product.getMiddleSortId()).toString();
}
@Override
public int getMaxCount() {
return 4;
}
});
return results;
private boolean isCommonStrategy(StrategyEnum strategy) {
return strategy.equals(StrategyEnum.COMMON) || strategy.equals(StrategyEnum.COMMON_HEAT_VALUE) || strategy.equals(StrategyEnum.COMMON_CTR_VALUE);
}
/**
... ... @@ -289,21 +290,21 @@ public class UserRecallResponseBuilder {
iterator = sknResultList.iterator();
while (iterator.hasNext()) {
RecallMergerResult.SknResult sknResult = iterator.next();
if (!Arrays.asList(StrategyEnum.DIRECT_TRAIN,StrategyEnum.REC_SKN,StrategyEnum.RT_SIM_SKN).contains(sknResult.getStrategy())){
if (!Arrays.asList(StrategyEnum.DIRECT_TRAIN, StrategyEnum.REC_SKN, StrategyEnum.RT_SIM_SKN).contains(sknResult.getStrategy())) {
results.add(sknResult);
iterator.remove();
}
}
// 3、插入【REC_SKN】的商品-随机插入
this.addByIndexIndex(sknResultList, results, 1, 2, (sknResult -> StrategyEnum.REC_SKN.equals(sknResult.getStrategy())),dropTransfer);
this.addByIndexIndex(sknResultList, results, 1, 2, (sknResult -> StrategyEnum.REC_SKN.equals(sknResult.getStrategy())), dropTransfer);
// 4、插入【RT_SIM_SKN】的商品-随机插入
this.addByIndexIndex(sknResultList, results, 2, 3, (sknResult -> StrategyEnum.RT_SIM_SKN.equals(sknResult.getStrategy())),dropTransfer);
this.addByIndexIndex(sknResultList, results, 2, 3, (sknResult -> StrategyEnum.RT_SIM_SKN.equals(sknResult.getStrategy())), dropTransfer);
// 4、插入【直通车】商品-随机插入
// 5、插入【直通车】商品-随机插入
int directTrainIndexInterval = searchDynamicConfigService.directTrainIndexInterval();
this.addByIndexIndex(sknResultList, results, 4, directTrainIndexInterval, (sknResult -> StrategyEnum.DIRECT_TRAIN.equals(sknResult.getStrategy())),dropTransfer);
this.addByIndexIndex(sknResultList, results, 4, directTrainIndexInterval, (sknResult -> StrategyEnum.DIRECT_TRAIN.equals(sknResult.getStrategy())), dropTransfer);
return results;
}
... ... @@ -311,9 +312,9 @@ public class UserRecallResponseBuilder {
/**
* 单策略召回时,超出数量直接丢弃
*/
private static Transfer<RecallMergerResult.SknResult,Boolean> dropTransfer = (sknResult) ->sknResult.isOnlyOneStrategy()?true:false;
private static Transfer<RecallMergerResult.SknResult, Boolean> dropTransfer = (sknResult) -> sknResult.isOnlyOneStrategy() ? true : false;
private static <T> void addByIndexIndex(List<T> fromList, List<T> toList,int fromIndex, int indexInterval,Transfer<T, Boolean> match,Transfer<T, Boolean> drop) {
private static <T> void addByIndexIndex(List<T> fromList, List<T> toList, int fromIndex, int indexInterval, Transfer<T, Boolean> match, Transfer<T, Boolean> drop) {
Iterator<T> iterator = fromList.iterator();
while (iterator.hasNext()) {
T object = iterator.next();
... ... @@ -329,35 +330,35 @@ public class UserRecallResponseBuilder {
//超出新列表的长度,判断是否直接丢弃
if (fromIndex <= toListNewSize) {
toList.add(fromIndex, object);
}else if(drop !=null && !drop.transfer(object)){
} else if (drop != null && !drop.transfer(object)) {
toList.add(object);
}
iterator.remove();
fromIndex = fromIndex + indexInterval;
if(indexInterval>1){
fromIndex = fromIndex + (int)(indexInterval * Math.random());
}else{
fromIndex = fromIndex + (Math.random()>0.5?1:0);
if (indexInterval > 1) {
fromIndex = fromIndex + (int) (indexInterval * Math.random());
} else {
fromIndex = fromIndex + (Math.random() > 0.5 ? 1 : 0);
}
}
}
public static void main(String[] args) {
List<Integer> userPriceAreas = new ArrayList<>();
userPriceAreas.addAll(Arrays.asList(5,6,7));
userPriceAreas.addAll(Arrays.asList(5, 6, 7));
Collections.sort(userPriceAreas);
int min = userPriceAreas.get(0);
int max = userPriceAreas.get(userPriceAreas.size()-1);
int leftCount = min<=1 ? 0 : max>=7 ? 2 : 1;
int rightCount = min<=1 ? 2 : max>=7 ? 0 : 1;
for(int i = 1;i<=leftCount;i++){
if(min-i>=1){
userPriceAreas.add(0,min-i);
int max = userPriceAreas.get(userPriceAreas.size() - 1);
int leftCount = min <= 1 ? 0 : max >= 7 ? 2 : 1;
int rightCount = min <= 1 ? 2 : max >= 7 ? 0 : 1;
for (int i = 1; i <= leftCount; i++) {
if (min - i >= 1) {
userPriceAreas.add(0, min - i);
}
}
for(int i = 1;i<=rightCount;i++){
if(max+i<=7){
userPriceAreas.add(max+i);
for (int i = 1; i <= rightCount; i++) {
if (max + i <= 7) {
userPriceAreas.add(max + i);
}
}
System.out.println(userPriceAreas);
... ...
... ... @@ -18,9 +18,10 @@ public class ExtendFilterHelper {
/**
* 流量补偿的过滤器
*
* @return
*/
public static QueryBuilder addFlowFilter (){
public static QueryBuilder addFlowFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.termQuery(ProductIndexEsField.flowType, "1"));
filter.mustNot(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
... ... @@ -30,9 +31,10 @@ public class ExtendFilterHelper {
/**
* 直通车的过滤器
*
* @return
*/
public static QueryBuilder directTrainFilter (){
public static QueryBuilder directTrainFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.termQuery(ProductIndexEsField.toAddScore, "Y"));
filter.mustNot(QueryBuilders.rangeQuery(ProductIndexEsField.breakSizePercent).gt(50));
... ... @@ -42,26 +44,29 @@ public class ExtendFilterHelper {
/**
* firstSkn的过滤器
*
* @return
*/
public static QueryBuilder firstSknFilter (List<String> firstSkns){
public static QueryBuilder firstSknFilter(List<String> firstSkns) {
return QueryBuilders.termsQuery(ProductIndexEsField.productSkn, firstSkns);
}
/**
* firstSkn的过滤器
*
* @return
*/
public static QueryBuilder productSknFilter (Integer productSkn){
public static QueryBuilder productSknFilter(Integer productSkn) {
return QueryBuilders.termQuery(ProductIndexEsField.productSkn, productSkn);
}
/**
* 新开店铺的过滤器-开店时间30天内,非流量惩罚的
*
* @return
*/
public static QueryBuilder newShopFilter (){
public static QueryBuilder newShopFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(QueryBuilders.rangeQuery(ProductIndexEsField.shopCreateTime).gte(DateUtil.getFirstTimeSecond(DateUtil.addDay(new Date(), -30))));
... ... @@ -72,17 +77,45 @@ public class ExtendFilterHelper {
/**
* 兜底策略的过滤器-不能加任何额外条件
*
* @return
*/
public static QueryBuilder commonFilter (){
public static QueryBuilder commonFilter() {
return null;
}
/**
* 不能加任何额外条件
*
* @return
*/
public static QueryBuilder commonCtrValueFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.rangeQuery(ProductIndexEsField.ctrValue).gt(0));
//must not
filter.mustNot(notRecallFilter());
return filter;
}
/**
* 不能加任何额外条件
*
* @return
*/
public static QueryBuilder commonHeatValueFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.rangeQuery(ProductIndexEsField.heatValue).gt(0));
//must not
filter.mustNot(notRecallFilter());
return filter;
}
/**
* 【品类+品牌】人气-【除去新品,新降价和新开促销】
*
* @return
*/
public static QueryBuilder sortBrandHeatValue (SortBrand sortBrand){
public static QueryBuilder sortBrandHeatValue(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(sortBrandIdFilter(sortBrand));
... ... @@ -96,9 +129,10 @@ public class ExtendFilterHelper {
/**
* 【品类+品牌】人气-【除去新品,新降价和新开促销】
*
* @return
*/
public static QueryBuilder sortBrandCtrValue (SortBrand sortBrand){
public static QueryBuilder sortBrandCtrValue(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(sortBrandIdFilter(sortBrand));
... ... @@ -113,9 +147,10 @@ public class ExtendFilterHelper {
/**
* 【品类+品牌】新品
*
* @return
*/
public static QueryBuilder sortBrandNewFilter (SortBrand sortBrand){
public static QueryBuilder sortBrandNewFilter(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(sortBrandIdFilter(sortBrand));
... ... @@ -129,9 +164,10 @@ public class ExtendFilterHelper {
/**
* 【品类+品牌】新降价
*
* @return
*/
public static QueryBuilder sortBrandReducePrice (SortBrand sortBrand){
public static QueryBuilder sortBrandReducePrice(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(sortBrandIdFilter(sortBrand));
... ... @@ -145,9 +181,10 @@ public class ExtendFilterHelper {
/**
* 【品类+品牌】新开促销
*
* @return
*/
public static QueryBuilder sortBrandPromotion (SortBrand sortBrand){
public static QueryBuilder sortBrandPromotion(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(sortBrandIdFilter(sortBrand));
... ... @@ -160,7 +197,7 @@ public class ExtendFilterHelper {
}
private static QueryBuilder sortBrandIdFilter (SortBrand sortBrand){
private static QueryBuilder sortBrandIdFilter(SortBrand sortBrand) {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.must(QueryBuilders.termQuery(ProductIndexEsField.brandId, sortBrand.getBrandId()));
filter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, sortBrand.getMisort()));
... ... @@ -170,15 +207,15 @@ public class ExtendFilterHelper {
private static final List<String> PromotionsTypes = Arrays.asList("Cashreduce", "Cheapestfree", "Degressdiscount", "Discount", "SpecifiedAmount");
private static QueryBuilder newFilter (){
return QueryBuilders.termsQuery(ProductIndexEsField.isnew,"Y");
private static QueryBuilder newFilter() {
return QueryBuilders.termsQuery(ProductIndexEsField.isnew, "Y");
}
private static QueryBuilder latestReducePriceFilter (){
private static QueryBuilder latestReducePriceFilter() {
return QueryBuilders.termQuery(ProductIndexEsField.isLatestReducePrice, "Y");
}
private static QueryBuilder isNewPromotionFilter (){
private static QueryBuilder isNewPromotionFilter() {
BoolQueryBuilder nestedFilter = QueryBuilders.boolQuery();
long hourFirstTime = DateUtil.getHourFirstTimeSecond(new Date());
nestedFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsStartTime).lt(hourFirstTime));
... ... @@ -189,9 +226,10 @@ public class ExtendFilterHelper {
/**
* 不召回的过滤条件
*
* @return
*/
public static QueryBuilder notRecallFilter(){
public static QueryBuilder notRecallFilter() {
BoolQueryBuilder filter = QueryBuilders.boolQuery();
filter.should(QueryBuilders.termQuery(ProductIndexEsField.flowType, "2"));
filter.should(QueryBuilders.termQuery(ProductIndexEsField.isGlobal, "Y"));
... ...
... ... @@ -29,8 +29,10 @@ public enum StrategyEnum {
ADD_FLOW(12),//流量补偿
NEW_SHOP(11),//新开店铺
COMMON(1),//整个页面的人气兜底
DEFAULT(0);//其他,无视即可
COMMON_CTR_VALUE(2),//整个页面的点击率召回
COMMON_HEAT_VALUE(1),//整个页面的人气召回
COMMON(0),//兜底,其他策略数量足够时召回来的商品会丢弃
DEFAULT(-1);//其他,无视即可
private Integer priority;
... ...
package com.yoho.search.recall.scene.beans.strategy.impls;
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.IStrategy;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import com.yoho.search.recall.scene.constants.CacheTimeConstants;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
/**
* 直通车的召回
*
* @author gufei.hu
*
*/
public class CommonCtrValueStrategy implements IStrategy {
private int size;
public CommonCtrValueStrategy(int size) {
this.size = size;
}
@Override
public StrategyEnum strategtEnum() {
return StrategyEnum.COMMON_CTR_VALUE;
}
@Override
public QueryBuilder extendFilter() {
return ExtendFilterHelper.commonCtrValueFilter();
}
@Override
public SortBuilder<?> sortBuilder() {
return SortBuilderHelper.getCtrValueDescSort();
}
@Override
public int size() {
return size;
}
@Override
public int cacheTimeInMinute() {
return CacheTimeConstants.COMMON_RECALL_STRATEGY_CACHE_TIME;
}
@Override
public String strategyCacheKey() {
StringBuilder sb = defaultStrategyKey();
return sb.toString();
}
}
... ...
... ... @@ -24,12 +24,12 @@ public class CommonHeatValueStrategy implements IStrategy {
@Override
public StrategyEnum strategtEnum() {
return StrategyEnum.COMMON;
return StrategyEnum.COMMON_HEAT_VALUE;
}
@Override
public QueryBuilder extendFilter() {
return ExtendFilterHelper.commonFilter();
return ExtendFilterHelper.commonHeatValueFilter();
}
@Override
... ...
package com.yoho.search.recall.scene.beans.strategy.impls;
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.IStrategy;
import com.yoho.search.recall.scene.beans.strategy.StrategyEnum;
import com.yoho.search.recall.scene.constants.CacheTimeConstants;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
/**
* 真正兜底的召回
*
* @author gufei.hu
*
*/
public class CommonStrategy implements IStrategy {
private int size;
public CommonStrategy(int size) {
this.size = size;
}
@Override
public StrategyEnum strategtEnum() {
return StrategyEnum.COMMON;
}
@Override
public QueryBuilder extendFilter() {
return ExtendFilterHelper.commonFilter();
}
@Override
public SortBuilder<?> sortBuilder() {
return SortBuilderHelper.getHeatValueDescSort();
}
@Override
public int size() {
return size;
}
@Override
public int cacheTimeInMinute() {
return CacheTimeConstants.COMMON_RECALL_STRATEGY_CACHE_TIME;
}
@Override
public String strategyCacheKey() {
StringBuilder sb = defaultStrategyKey();
return sb.toString();
}
}
... ...
... ... @@ -5,7 +5,8 @@ public class SknCountConstants {
/**
* 单次召回的商品数量
*/
public static final int COMMON_HEAT_VALUE = 20;
public static final int COMMON_HEAT_VALUE = 100;
public static final int COMMON_CTR_VALUE = 100;
public static final int FIRST_SKN = 1;
public static final int DIRECT_TRAIN_RECALL_COUNT = 100;
... ... @@ -15,6 +16,6 @@ public class SknCountConstants {
public static final int SORT_BRAND_RECALL_STRATEGY_SKN_COUNT = 8;
public static final int MAX_USER_RECALL_SKN_CACHE_COUNT = 100;
public static final int MAX_USER_RECALL_SKN_CACHE_COUNT = 200;
}
... ...