Authored by hugufei

Merge branch 'zj' into 6.2

1 package com.yoho.search.service.base; 1 package com.yoho.search.service.base;
2 2
  3 +import java.util.ArrayList;
  4 +import java.util.List;
  5 +
  6 +import org.apache.commons.lang.StringUtils;
3 import org.slf4j.Logger; 7 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory; 8 import org.slf4j.LoggerFactory;
5 import org.springframework.beans.factory.annotation.Autowired; 9 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Service; 10 import org.springframework.stereotype.Service;
7 11
  12 +import com.alibaba.fastjson.JSON;
8 import com.yoho.core.config.ConfigReader; 13 import com.yoho.core.config.ConfigReader;
  14 +import com.yoho.search.base.models.PageRecallStrategyBO;
9 import com.yoho.search.common.downgrade.persional.PersionalRateLimit; 15 import com.yoho.search.common.downgrade.persional.PersionalRateLimit;
10 import com.yoho.search.common.downgrade.persional.PersionalRateLimitConfig; 16 import com.yoho.search.common.downgrade.persional.PersionalRateLimitConfig;
11 17
@@ -13,7 +19,7 @@ import com.yoho.search.common.downgrade.persional.PersionalRateLimitConfig; @@ -13,7 +19,7 @@ import com.yoho.search.common.downgrade.persional.PersionalRateLimitConfig;
13 public class SearchDynamicConfigService { 19 public class SearchDynamicConfigService {
14 20
15 private static final Logger logger = LoggerFactory.getLogger(SearchDynamicConfigService.class); 21 private static final Logger logger = LoggerFactory.getLogger(SearchDynamicConfigService.class);
16 - 22 +
17 @Autowired 23 @Autowired
18 private ConfigReader configReader; 24 private ConfigReader configReader;
19 25
@@ -180,13 +186,13 @@ public class SearchDynamicConfigService { @@ -180,13 +186,13 @@ public class SearchDynamicConfigService {
180 public boolean isSortPageRecallOpen() { 186 public boolean isSortPageRecallOpen() {
181 return configReader.getBoolean("search.sortpage.recall.open", true); 187 return configReader.getBoolean("search.sortpage.recall.open", true);
182 } 188 }
183 - 189 +
184 /** 190 /**
185 * 品类页召回时使用的uid[尾数] 191 * 品类页召回时使用的uid[尾数]
186 */ 192 */
187 public boolean isGoToSortRecallUser(int uid) { 193 public boolean isGoToSortRecallUser(int uid) {
188 String uidMantissas = configReader.getString("search.sortpage.recall.uid.mantissa", "5"); 194 String uidMantissas = configReader.getString("search.sortpage.recall.uid.mantissa", "5");
189 - if(uidMantissas.contains(String.valueOf(uid % 10))){ 195 + if (uidMantissas.contains(String.valueOf(uid % 10))) {
190 return true; 196 return true;
191 } 197 }
192 return false; 198 return false;
@@ -198,28 +204,43 @@ public class SearchDynamicConfigService { @@ -198,28 +204,43 @@ public class SearchDynamicConfigService {
198 public boolean isSortPageRecallUseGlobalBrand() { 204 public boolean isSortPageRecallUseGlobalBrand() {
199 return configReader.getBoolean("search.sortpage.recall.use_global_brand", false); 205 return configReader.getBoolean("search.sortpage.recall.use_global_brand", false);
200 } 206 }
201 - 207 +
202 /** 208 /**
203 * 个性化限流开关 209 * 个性化限流开关
204 */ 210 */
205 public boolean isPersionalRateLimitOpen() { 211 public boolean isPersionalRateLimitOpen() {
206 return configReader.getBoolean("search.persional.rateLimit.open", true); 212 return configReader.getBoolean("search.persional.rateLimit.open", true);
207 } 213 }
208 - 214 +
209 /** 215 /**
210 * 个性化限流配置 216 * 个性化限流配置
211 */ 217 */
212 - public PersionalRateLimitConfig getPersionalRateLimitConfig(String rateLimitName,PersionalRateLimit persionalRateLimit){ 218 + public PersionalRateLimitConfig getPersionalRateLimitConfig(String rateLimitName, PersionalRateLimit persionalRateLimit) {
213 try { 219 try {
214 String zkConfigKey = "search.persional.rateLimit" + rateLimitName.replaceAll("/", "."); 220 String zkConfigKey = "search.persional.rateLimit" + rateLimitName.replaceAll("/", ".");
215 PersionalRateLimitConfig defalut = new PersionalRateLimitConfig(persionalRateLimit); 221 PersionalRateLimitConfig defalut = new PersionalRateLimitConfig(persionalRateLimit);
216 String zkConfigValue = configReader.getString(zkConfigKey, defalut.toZkValue()); 222 String zkConfigValue = configReader.getString(zkConfigKey, defalut.toZkValue());
217 return new PersionalRateLimitConfig(zkConfigValue); 223 return new PersionalRateLimitConfig(zkConfigValue);
218 } catch (Exception e) { 224 } catch (Exception e) {
219 - logger.error(e.getMessage(),e);  
220 - return new PersionalRateLimitConfig(200,10); 225 + logger.error(e.getMessage(), e);
  226 + return new PersionalRateLimitConfig(200, 10);
  227 + }
  228 + }
  229 +
  230 + /**
  231 + * 召回策略配置
  232 + */
  233 + public List<PageRecallStrategyBO> getPageRecallStrategyBOs() {
  234 + try {
  235 + String recallStrategyValues = configReader.getString("search.recallstrategy.values", "");
  236 + if(StringUtils.isBlank(recallStrategyValues)){
  237 + return new ArrayList<PageRecallStrategyBO>();
  238 + }
  239 + return JSON.parseArray(recallStrategyValues, PageRecallStrategyBO.class);
  240 + } catch (Exception e) {
  241 + logger.error(e.getMessage(), e);
  242 + return new ArrayList<PageRecallStrategyBO>();
221 } 243 }
222 } 244 }
223 245
224 -  
225 } 246 }
@@ -28,11 +28,11 @@ import com.alibaba.fastjson.JSON; @@ -28,11 +28,11 @@ import com.alibaba.fastjson.JSON;
28 import com.alibaba.fastjson.JSONArray; 28 import com.alibaba.fastjson.JSONArray;
29 import com.alibaba.fastjson.JSONObject; 29 import com.alibaba.fastjson.JSONObject;
30 import com.yoho.search.base.models.RecallType; 30 import com.yoho.search.base.models.RecallType;
31 -import com.yoho.search.base.utils.CollectionUtils;  
32 import com.yoho.search.base.utils.ConvertUtils; 31 import com.yoho.search.base.utils.ConvertUtils;
33 import com.yoho.search.base.utils.ISearchConstants; 32 import com.yoho.search.base.utils.ISearchConstants;
34 import com.yoho.search.base.utils.JsonUtil; 33 import com.yoho.search.base.utils.JsonUtil;
35 import com.yoho.search.base.utils.ProductIndexEsField; 34 import com.yoho.search.base.utils.ProductIndexEsField;
  35 +import com.yoho.search.base.utils.SearchPageIdDefine;
36 import com.yoho.search.core.es.model.SearchParam; 36 import com.yoho.search.core.es.model.SearchParam;
37 import com.yoho.search.core.es.model.SearchResult; 37 import com.yoho.search.core.es.model.SearchResult;
38 import com.yoho.search.core.personalized.BigDataRedisService; 38 import com.yoho.search.core.personalized.BigDataRedisService;
@@ -51,15 +51,8 @@ import com.yoho.search.service.scene.recall.model.RecallProductInfoList; @@ -51,15 +51,8 @@ import com.yoho.search.service.scene.recall.model.RecallProductInfoList;
51 import com.yoho.search.service.scene.recall.model.RecallProductSknList; 51 import com.yoho.search.service.scene.recall.model.RecallProductSknList;
52 import com.yoho.search.service.scene.recall.model.RecallResult; 52 import com.yoho.search.service.scene.recall.model.RecallResult;
53 import com.yoho.search.service.scene.recall.model.RecallSearchResult; 53 import com.yoho.search.service.scene.recall.model.RecallSearchResult;
54 -import com.yoho.search.service.scene.recall.strategy.AddFlowStrategy;  
55 -import com.yoho.search.service.scene.recall.strategy.CommonStrategy;  
56 -import com.yoho.search.service.scene.recall.strategy.DirectTrainStrategy;  
57 -import com.yoho.search.service.scene.recall.strategy.FirstProductSknStrategy;  
58 import com.yoho.search.service.scene.recall.strategy.IRecallStrategy; 54 import com.yoho.search.service.scene.recall.strategy.IRecallStrategy;
59 -import com.yoho.search.service.scene.recall.strategy.NewPromotionStrategy;  
60 -import com.yoho.search.service.scene.recall.strategy.NewReducePriceStrategy;  
61 -import com.yoho.search.service.scene.recall.strategy.NewShelveStrategy;  
62 -import com.yoho.search.service.scene.recall.strategy.NewShopStrategy; 55 +import com.yoho.search.service.scene.recall.strategy.RecallStrategyFactory;
63 import com.yoho.search.service.service.IProductIndexService; 56 import com.yoho.search.service.service.IProductIndexService;
64 57
65 @Service 58 @Service
@@ -87,6 +80,8 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -87,6 +80,8 @@ public class SortRecallSceneService extends AbstractRecallService {
87 private ProductListSortService productListSortService; 80 private ProductListSortService productListSortService;
88 @Autowired 81 @Autowired
89 private SearchCommonHelper searchCommonHelper; 82 private SearchCommonHelper searchCommonHelper;
  83 + @Autowired
  84 + private RecallStrategyFactory recallStrategyFactory;
90 85
91 /** 86 /**
92 * @品类页商品召回接口 87 * @品类页商品召回接口
@@ -347,8 +342,6 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -347,8 +342,6 @@ public class SortRecallSceneService extends AbstractRecallService {
347 */ 342 */
348 @Override 343 @Override
349 protected List<IRecallStrategy> getRecallStrategys(Map<String, String> paramMap) { 344 protected List<IRecallStrategy> getRecallStrategys(Map<String, String> paramMap) {
350 - List<IRecallStrategy> recallStrategy = new ArrayList<IRecallStrategy>();  
351 - int pageSize = this.getPageSize(paramMap);  
352 // 0、获取用户偏好品牌 345 // 0、获取用户偏好品牌
353 List<Integer> brandIds = null; 346 List<Integer> brandIds = null;
354 long begin = System.currentTimeMillis(); 347 long begin = System.currentTimeMillis();
@@ -357,33 +350,39 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -357,33 +350,39 @@ public class SortRecallSceneService extends AbstractRecallService {
357 super.doLogInfo("[func0=getUserGlobalBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds)); 350 super.doLogInfo("[func0=getUserGlobalBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds));
358 } else { 351 } else {
359 brandIds = this.getUserLikeBrandIds(paramMap); 352 brandIds = this.getUserLikeBrandIds(paramMap);
360 - super.doLogInfo("[func0=getUserLikeBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds)); 353 + super.doLogInfo("[func0=getUserLikeBrandIds][cost={}ms],brandIds is {}]", System.currentTimeMillis() - begin, JSON.toJSONString(brandIds));
361 } 354 }
362 -  
363 - // 1、支持firstProductSkn的召回  
364 - recallStrategy.add(new FirstProductSknStrategy(1, this.getFirstProductSkns(paramMap)));  
365 - // 2、支持直通车的召回-随机召回  
366 - recallStrategy.add(new DirectTrainStrategy(2));  
367 - // 3、支持曝光补偿的召回-大数据给的,随机召回  
368 - recallStrategy.add(new AddFlowStrategy(2));  
369 - // 4、新开店铺商品召回-随机召回  
370 - recallStrategy.add(new NewShopStrategy(2));  
371 - // 5、支持新上架的召回-有new标签的  
372 - recallStrategy.add(new NewShelveStrategy(brandIds, 20));  
373 - // 6、支持新降价的召回-两天内实际降过价的  
374 - recallStrategy.add(new NewReducePriceStrategy(brandIds, 20));  
375 - // 7、支持新开促销的召回-5种促销类型  
376 - recallStrategy.add(new NewPromotionStrategy(brandIds, 20));  
377 - // 8、支持兜底的召回-人气排序  
378 - recallStrategy.add(new CommonStrategy(pageSize));  
379 - return recallStrategy; 355 + // 1、通过配置生成召回策略
  356 + return recallStrategyFactory.getRecallStrategys(paramMap, SearchPageIdDefine.PAGE_ID_SORT, brandIds);
  357 + // List<IRecallStrategy> recallStrategy = new
  358 + // ArrayList<IRecallStrategy>();
  359 + // int pageSize = this.getPageSize(paramMap);
  360 + // // 1、支持firstProductSkn的召回
  361 + // recallStrategy.add(new FirstProductSknStrategy(1,
  362 + // this.getFirstProductSkns(paramMap)));
  363 + // // 2、支持直通车的召回-随机召回
  364 + // recallStrategy.add(new DirectTrainStrategy(2));
  365 + // // 3、支持曝光补偿的召回-大数据给的,随机召回
  366 + // recallStrategy.add(new AddFlowStrategy(2));
  367 + // // 4、新开店铺商品召回-随机召回
  368 + // recallStrategy.add(new NewShopStrategy(2));
  369 + // // 5、支持新上架的召回-有new标签的
  370 + // recallStrategy.add(new NewShelveStrategy(brandIds, 20));
  371 + // // 6、支持新降价的召回-两天内实际降过价的
  372 + // recallStrategy.add(new NewReducePriceStrategy(brandIds, 20));
  373 + // // 7、支持新开促销的召回-5种促销类型
  374 + // recallStrategy.add(new NewPromotionStrategy(brandIds, 20));
  375 + // // 8、支持兜底的召回-人气排序
  376 + // recallStrategy.add(new CommonStrategy(pageSize));
  377 + // return recallStrategy;
380 } 378 }
381 379
382 - private List<String> getFirstProductSkns(Map<String, String> paramMap) {  
383 - String firstProductSkns = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_FIRST_PRODUCRSKN, "");  
384 - String[] firstProductSknArray = firstProductSkns.split(",");  
385 - return CollectionUtils.arrayToList(firstProductSknArray);  
386 - } 380 + // private List<String> getFirstProductSkns(Map<String, String> paramMap) {
  381 + // String firstProductSkns = MapUtils.getString(paramMap,
  382 + // SearchRequestParams.PARAM_SEARCH_FIRST_PRODUCRSKN, "");
  383 + // String[] firstProductSknArray = firstProductSkns.split(",");
  384 + // return CollectionUtils.arrayToList(firstProductSknArray);
  385 + // }
387 386
388 /** 387 /**
389 * 粗排-各类型之间去重 388 * 粗排-各类型之间去重
@@ -401,7 +400,7 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -401,7 +400,7 @@ public class SortRecallSceneService extends AbstractRecallService {
401 iterator.remove(); 400 iterator.remove();
402 } else { 401 } else {
403 existProductSkns.add(productSkn); 402 existProductSkns.add(productSkn);
404 - product.put("recallType", recallSearchResult.getRecallType()); 403 + product.put("recallType", recallSearchResult.getRecallType().getId());
405 productList.add(product); 404 productList.add(product);
406 } 405 }
407 } 406 }
@@ -420,7 +419,7 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -420,7 +419,7 @@ public class SortRecallSceneService extends AbstractRecallService {
420 Iterator<Map<String, Object>> iterator = productList.iterator(); 419 Iterator<Map<String, Object>> iterator = productList.iterator();
421 while (iterator.hasNext()) { 420 while (iterator.hasNext()) {
422 Map<String, Object> product = iterator.next(); 421 Map<String, Object> product = iterator.next();
423 - if (!product.get("recallType").equals(RecallType.COMMON)) { 422 + if (!product.get("recallType").equals(RecallType.COMMON.getId())) {
424 results.add(product); 423 results.add(product);
425 iterator.remove(); 424 iterator.remove();
426 } 425 }
@@ -441,7 +440,7 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -441,7 +440,7 @@ public class SortRecallSceneService extends AbstractRecallService {
441 Iterator<Map<String, Object>> iterator = productList.iterator(); 440 Iterator<Map<String, Object>> iterator = productList.iterator();
442 while (iterator.hasNext()) { 441 while (iterator.hasNext()) {
443 Map<String, Object> product = iterator.next(); 442 Map<String, Object> product = iterator.next();
444 - if (product.get("recallType").equals(RecallType.FIRST_PRODUCT_SKN)) { 443 + if (product.get("recallType").equals(RecallType.FIRST_PRODUCT_SKN.getId())) {
445 newProductList.add(product); 444 newProductList.add(product);
446 iterator.remove(); 445 iterator.remove();
447 break; 446 break;
@@ -451,7 +450,7 @@ public class SortRecallSceneService extends AbstractRecallService { @@ -451,7 +450,7 @@ public class SortRecallSceneService extends AbstractRecallService {
451 iterator = productList.iterator(); 450 iterator = productList.iterator();
452 while (iterator.hasNext()) { 451 while (iterator.hasNext()) {
453 Map<String, Object> product = iterator.next(); 452 Map<String, Object> product = iterator.next();
454 - if (!product.get("recallType").equals(RecallType.DIRECT_TRAIN)) { 453 + if (!product.get("recallType").equals(RecallType.DIRECT_TRAIN.getId())) {
455 newProductList.add(product); 454 newProductList.add(product);
456 iterator.remove(); 455 iterator.remove();
457 } 456 }
@@ -24,6 +24,10 @@ public class AddFlowStrategy implements IRecallStrategy { @@ -24,6 +24,10 @@ public class AddFlowStrategy implements IRecallStrategy {
24 public AddFlowStrategy(int size) { 24 public AddFlowStrategy(int size) {
25 this.size = size; 25 this.size = size;
26 } 26 }
  27 +
  28 + public AddFlowStrategy(StrategyConstructor strategyConstructor) {
  29 + this.size = strategyConstructor.getSize();
  30 + }
27 31
28 @Override 32 @Override
29 public RecallType recallType() { 33 public RecallType recallType() {
@@ -15,6 +15,10 @@ public class CommonStrategy implements IRecallStrategy { @@ -15,6 +15,10 @@ public class CommonStrategy implements IRecallStrategy {
15 public CommonStrategy(int size){ 15 public CommonStrategy(int size){
16 this.size = size; 16 this.size = size;
17 } 17 }
  18 +
  19 + public CommonStrategy(StrategyConstructor strategyConstructor) {
  20 + this.size = strategyConstructor.getSize();
  21 + }
18 22
19 @Override 23 @Override
20 public RecallType recallType() { 24 public RecallType recallType() {
@@ -25,6 +25,10 @@ public class DirectTrainStrategy implements IRecallStrategy { @@ -25,6 +25,10 @@ public class DirectTrainStrategy implements IRecallStrategy {
25 public DirectTrainStrategy(int size) { 25 public DirectTrainStrategy(int size) {
26 this.size = size; 26 this.size = size;
27 } 27 }
  28 +
  29 + public DirectTrainStrategy(StrategyConstructor strategyConstructor) {
  30 + this.size = strategyConstructor.getSize();
  31 + }
28 32
29 @Override 33 @Override
30 public RecallType recallType() { 34 public RecallType recallType() {
1 package com.yoho.search.service.scene.recall.strategy; 1 package com.yoho.search.service.scene.recall.strategy;
2 2
3 import java.util.List; 3 import java.util.List;
  4 +import java.util.Map;
4 5
  6 +import org.apache.commons.collections.MapUtils;
5 import org.elasticsearch.index.query.QueryBuilder; 7 import org.elasticsearch.index.query.QueryBuilder;
6 import org.elasticsearch.index.query.QueryBuilders; 8 import org.elasticsearch.index.query.QueryBuilders;
7 import org.elasticsearch.search.sort.SortBuilder; 9 import org.elasticsearch.search.sort.SortBuilder;
@@ -9,7 +11,9 @@ import org.elasticsearch.search.sort.SortBuilders; @@ -9,7 +11,9 @@ import org.elasticsearch.search.sort.SortBuilders;
9 import org.elasticsearch.search.sort.SortOrder; 11 import org.elasticsearch.search.sort.SortOrder;
10 12
11 import com.yoho.search.base.models.RecallType; 13 import com.yoho.search.base.models.RecallType;
  14 +import com.yoho.search.base.utils.CollectionUtils;
12 import com.yoho.search.base.utils.ProductIndexEsField; 15 import com.yoho.search.base.utils.ProductIndexEsField;
  16 +import com.yoho.search.service.base.SearchRequestParams;
13 17
14 /** 18 /**
15 * firstProductSkn的召回策略 19 * firstProductSkn的召回策略
@@ -22,16 +26,22 @@ public class FirstProductSknStrategy implements IRecallStrategy { @@ -22,16 +26,22 @@ public class FirstProductSknStrategy implements IRecallStrategy {
22 private int size; 26 private int size;
23 private List<String> firstProductSkns; 27 private List<String> firstProductSkns;
24 28
25 - public FirstProductSknStrategy(List<String> firstProductSkns) {  
26 - this.firstProductSkns = firstProductSkns;  
27 - this.size = firstProductSkns.size();  
28 - }  
29 -  
30 public FirstProductSknStrategy(int size, List<String> firstProductSkns) { 29 public FirstProductSknStrategy(int size, List<String> firstProductSkns) {
31 this.firstProductSkns = firstProductSkns; 30 this.firstProductSkns = firstProductSkns;
32 this.size = size > firstProductSkns.size() ? size : firstProductSkns.size(); 31 this.size = size > firstProductSkns.size() ? size : firstProductSkns.size();
33 } 32 }
34 33
  34 + public FirstProductSknStrategy(StrategyConstructor strategyConstructor) {
  35 + this.firstProductSkns = this.getFirstProductSkns(strategyConstructor.getParamMap());
  36 + this.size = strategyConstructor.getSize() <= firstProductSkns.size() ? strategyConstructor.getSize() : firstProductSkns.size();
  37 + }
  38 +
  39 + private List<String> getFirstProductSkns(Map<String, String> paramMap) {
  40 + String firstProductSkns = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_FIRST_PRODUCRSKN, "");
  41 + String[] firstProductSknArray = firstProductSkns.split(",");
  42 + return CollectionUtils.arrayToList(firstProductSknArray);
  43 + }
  44 +
35 @Override 45 @Override
36 public RecallType recallType() { 46 public RecallType recallType() {
37 return RecallType.FIRST_PRODUCT_SKN; 47 return RecallType.FIRST_PRODUCT_SKN;
@@ -24,22 +24,36 @@ import com.yoho.search.base.utils.ProductIndexEsField; @@ -24,22 +24,36 @@ import com.yoho.search.base.utils.ProductIndexEsField;
24 * 24 *
25 */ 25 */
26 public class NewPromotionStrategy implements IRecallStrategy { 26 public class NewPromotionStrategy implements IRecallStrategy {
27 - 27 +
  28 + private static final List<String> PromotionsTypes = Arrays.asList("Cashreduce", "Cheapestfree", "Degressdiscount", "Discount", "SpecifiedAmount");
  29 +
28 private int size; 30 private int size;
29 private List<Integer> brandIds; 31 private List<Integer> brandIds;
30 private BoolQueryBuilder nestedFilter; 32 private BoolQueryBuilder nestedFilter;
31 33
32 - public NewPromotionStrategy(List<Integer> brandIds, int size) {  
33 - this.size = size;  
34 - this.brandIds = brandIds; 34 + private BoolQueryBuilder getNestedFilter() {
35 // 构建nested——filter 35 // 构建nested——filter
36 - nestedFilter = QueryBuilders.boolQuery(); 36 + BoolQueryBuilder nestedFilter = QueryBuilders.boolQuery();
37 long hourFirstTime = DateUtil.getHourFirstTimeSecond(new Date()); 37 long hourFirstTime = DateUtil.getHourFirstTimeSecond(new Date());
38 nestedFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsStartTime).lt(hourFirstTime)); 38 nestedFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsStartTime).lt(hourFirstTime));
39 nestedFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsEndTime).gte(hourFirstTime)); 39 nestedFilter.must(QueryBuilders.rangeQuery(ProductIndexEsField.matchedPromotionsEndTime).gte(hourFirstTime));
40 - nestedFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.matchedPromotionsType, Arrays.asList("Cashreduce","Cheapestfree","Degressdiscount","Discount","SpecifiedAmount"))); 40 + nestedFilter.must(QueryBuilders.termsQuery(ProductIndexEsField.matchedPromotionsType,PromotionsTypes));
  41 + return nestedFilter;
  42 + }
  43 +
  44 + public NewPromotionStrategy(List<Integer> brandIds, int size) {
  45 + this.size = size;
  46 + this.brandIds = brandIds;
  47 + this.nestedFilter = getNestedFilter();
  48 +
41 } 49 }
42 50
  51 + public NewPromotionStrategy(StrategyConstructor strategyConstructor) {
  52 + this.size = strategyConstructor.getSize();
  53 + this.brandIds = strategyConstructor.getBrandIds();
  54 + this.nestedFilter = getNestedFilter();
  55 + }
  56 +
43 @Override 57 @Override
44 public RecallType recallType() { 58 public RecallType recallType() {
45 return RecallType.NEW_PROMOTION; 59 return RecallType.NEW_PROMOTION;
@@ -52,7 +66,7 @@ public class NewPromotionStrategy implements IRecallStrategy { @@ -52,7 +66,7 @@ public class NewPromotionStrategy implements IRecallStrategy {
52 66
53 @Override 67 @Override
54 public QueryBuilder filter() { 68 public QueryBuilder filter() {
55 - BoolQueryBuilder filter = QueryBuilders.boolQuery(); 69 + BoolQueryBuilder filter = QueryBuilders.boolQuery();
56 filter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.flowType, "2")); 70 filter.mustNot(QueryBuilders.termQuery(ProductIndexEsField.flowType, "2"));
57 filter.must(QueryBuilders.nestedQuery(ProductIndexEsField.matchedPromotions, this.nestedFilter, ScoreMode.None)); 71 filter.must(QueryBuilders.nestedQuery(ProductIndexEsField.matchedPromotions, this.nestedFilter, ScoreMode.None));
58 if (brandIds != null && !brandIds.isEmpty()) { 72 if (brandIds != null && !brandIds.isEmpty()) {
@@ -60,7 +74,7 @@ public class NewPromotionStrategy implements IRecallStrategy { @@ -60,7 +74,7 @@ public class NewPromotionStrategy implements IRecallStrategy {
60 } 74 }
61 return filter; 75 return filter;
62 } 76 }
63 - 77 +
64 @Override 78 @Override
65 public SortBuilder<?> firstSortBuilder() { 79 public SortBuilder<?> firstSortBuilder() {
66 FieldSortBuilder activitySort = SortBuilders.fieldSort("matchedPromotions.startTime").order(SortOrder.DESC).setNestedPath("matchedPromotions").missing("_last"); 80 FieldSortBuilder activitySort = SortBuilders.fieldSort("matchedPromotions.startTime").order(SortOrder.DESC).setNestedPath("matchedPromotions").missing("_last");
@@ -27,7 +27,12 @@ public class NewReducePriceStrategy implements IRecallStrategy { @@ -27,7 +27,12 @@ public class NewReducePriceStrategy implements IRecallStrategy {
27 this.size = size; 27 this.size = size;
28 this.brandIds = brandIds; 28 this.brandIds = brandIds;
29 } 29 }
30 - 30 +
  31 + public NewReducePriceStrategy(StrategyConstructor strategyConstructor) {
  32 + this.size = strategyConstructor.getSize();
  33 + this.brandIds = strategyConstructor.getBrandIds();
  34 + }
  35 +
31 @Override 36 @Override
32 public RecallType recallType() { 37 public RecallType recallType() {
33 return RecallType.NEW_REDUCE_PRICE; 38 return RecallType.NEW_REDUCE_PRICE;
@@ -27,6 +27,11 @@ public class NewShelveStrategy implements IRecallStrategy { @@ -27,6 +27,11 @@ public class NewShelveStrategy implements IRecallStrategy {
27 this.brandIds = brandIds; 27 this.brandIds = brandIds;
28 this.size = size; 28 this.size = size;
29 } 29 }
  30 +
  31 + public NewShelveStrategy(StrategyConstructor strategyConstructor) {
  32 + this.size = strategyConstructor.getSize();
  33 + this.brandIds = strategyConstructor.getBrandIds();
  34 + }
30 35
31 @Override 36 @Override
32 public RecallType recallType() { 37 public RecallType recallType() {
@@ -22,7 +22,11 @@ public class NewShopStrategy implements IRecallStrategy { @@ -22,7 +22,11 @@ public class NewShopStrategy implements IRecallStrategy {
22 public NewShopStrategy(int size) { 22 public NewShopStrategy(int size) {
23 this.size = size; 23 this.size = size;
24 } 24 }
25 - 25 +
  26 + public NewShopStrategy(StrategyConstructor strategyConstructor) {
  27 + this.size = strategyConstructor.getSize();
  28 + }
  29 +
26 @Override 30 @Override
27 public RecallType recallType() { 31 public RecallType recallType() {
28 return RecallType.NEW_SHOP; 32 return RecallType.NEW_SHOP;
  1 +package com.yoho.search.service.scene.recall.strategy;
  2 +
  3 +import java.lang.reflect.Constructor;
  4 +import java.util.ArrayList;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.stream.Collectors;
  9 +
  10 +import javax.annotation.PostConstruct;
  11 +
  12 +import org.apache.commons.lang.StringUtils;
  13 +import org.slf4j.Logger;
  14 +import org.slf4j.LoggerFactory;
  15 +import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.stereotype.Component;
  17 +
  18 +import com.yoho.search.base.models.PageRecallStrategyBO;
  19 +import com.yoho.search.base.models.PageRecallStrategyBO.RecallStrategyBO;
  20 +import com.yoho.search.base.models.RecallType;
  21 +import com.yoho.search.base.models.RecallValueType;
  22 +import com.yoho.search.service.base.SearchDynamicConfigService;
  23 +import com.yoho.search.service.helper.SearchCommonHelper;
  24 +
  25 +@Component
  26 +public class RecallStrategyFactory {
  27 +
  28 + private static final Logger logger = LoggerFactory.getLogger(RecallStrategyFactory.class);
  29 +
  30 + @Autowired
  31 + private SearchDynamicConfigService searchDynamicConfigService;
  32 + @Autowired
  33 + private SearchCommonHelper searchCommonHelper;
  34 +
  35 + private Map<RecallType, Class<? extends IRecallStrategy>> classMap = new HashMap<RecallType, Class<? extends IRecallStrategy>>();
  36 +
  37 + @PostConstruct
  38 + void init() {
  39 + classMap.put(RecallType.FIRST_PRODUCT_SKN, FirstProductSknStrategy.class);
  40 + classMap.put(RecallType.DIRECT_TRAIN, DirectTrainStrategy.class);
  41 + classMap.put(RecallType.NEW_SHELVE, NewShelveStrategy.class);
  42 + classMap.put(RecallType.NEW_REDUCE_PRICE, NewReducePriceStrategy.class);
  43 + classMap.put(RecallType.NEW_PROMOTION, NewPromotionStrategy.class);
  44 + classMap.put(RecallType.NEW_SHOP, NewShopStrategy.class);
  45 + classMap.put(RecallType.ADD_FLOW, AddFlowStrategy.class);
  46 + classMap.put(RecallType.COMMON, CommonStrategy.class);
  47 + }
  48 +
  49 + /**
  50 + * 根据配置获取页面召回策略
  51 + *
  52 + * @param pageId
  53 + * @return
  54 + */
  55 + public List<IRecallStrategy> getRecallStrategys(Map<String, String> paramMap, String pageId, List<Integer> brandIds) {
  56 + List<PageRecallStrategyBO> pageRecallStrategyBO = searchDynamicConfigService.getPageRecallStrategyBOs();
  57 + Map<Integer, List<RecallStrategyBO>> map = pageRecallStrategyBO.stream().collect(Collectors.toMap(PageRecallStrategyBO::getPageId, PageRecallStrategyBO::getStrategies));
  58 + List<RecallStrategyBO> strategys = map.get(Integer.valueOf(pageId));
  59 + if (strategys == null || strategys.isEmpty()) {
  60 + return new ArrayList<IRecallStrategy>();
  61 + }
  62 + int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 60 : Integer.parseInt(paramMap.get("viewNum"));
  63 + List<IRecallStrategy> results = new ArrayList<IRecallStrategy>();
  64 + for (RecallStrategyBO recallStrategyBO : strategys) {
  65 + IRecallStrategy recallStrategy = this.getIRecallStrategy(recallStrategyBO, paramMap, pageSize, brandIds);
  66 + if (recallStrategy != null) {
  67 + logger.info("pageId is [{}],[name is [{}] , size is[{}]",pageId,recallStrategy.recallType().getName(),recallStrategy.size());
  68 + results.add(recallStrategy);
  69 + }
  70 + }
  71 + return results;
  72 + }
  73 +
  74 + private IRecallStrategy getIRecallStrategy(RecallStrategyBO recallStrategyBO, Map<String, String> paramMap, int pageSize, List<Integer> brandIds) {
  75 + try {
  76 + int size = this.getSize(recallStrategyBO, pageSize);
  77 + if (size == 0) {
  78 + return null;
  79 + }
  80 + RecallType recallType = RecallType.getById(recallStrategyBO.getRecallType());
  81 + if (recallType == null) {
  82 + return null;
  83 + }
  84 + Class<? extends IRecallStrategy> clazz = classMap.get(recallType);
  85 + if (clazz == null) {
  86 + return null;
  87 + }
  88 +
  89 + // 获取StrategyConstructor的构造函数
  90 + Constructor<? extends IRecallStrategy> c1 = clazz.getConstructor(StrategyConstructor.class);// 获取有参构造
  91 + if (c1 == null) {
  92 + return null;
  93 + }
  94 +
  95 + StrategyConstructor strategyConstructor = new StrategyConstructor(size, paramMap, brandIds);
  96 + return c1.newInstance(strategyConstructor);
  97 +
  98 + } catch (Exception e) {
  99 + logger.error(e.getMessage(), e);
  100 + return null;
  101 + }
  102 + }
  103 +
  104 + private int getSize(RecallStrategyBO recallStrategyBO, int pageSize) {
  105 + try {
  106 + if (RecallValueType.DEFAULT.getId() == recallStrategyBO.getValueType()) {
  107 + return pageSize;
  108 + }
  109 + if (RecallValueType.NUMBER.getId() == recallStrategyBO.getValueType()) {
  110 + return recallStrategyBO.getRecallValue();
  111 + }
  112 + if (RecallValueType.PERCENT.getId() == recallStrategyBO.getValueType()) {
  113 + return (int) (recallStrategyBO.getRecallValue() * pageSize / 100);
  114 + }
  115 + return 0;
  116 + } catch (Exception e) {
  117 + logger.error(e.getMessage(), e);
  118 + return 0;
  119 + }
  120 + }
  121 +
  122 +}
  1 +package com.yoho.search.service.scene.recall.strategy;
  2 +
  3 +import java.util.List;
  4 +import java.util.Map;
  5 +
  6 +
  7 +/**
  8 + * 各策略的构造参数
  9 + * @author gufei.hu
  10 + *
  11 + */
  12 +public class StrategyConstructor {
  13 +
  14 + private int size;
  15 + private Map<String,String> paramMap;
  16 + private List<Integer> brandIds;
  17 +
  18 + public StrategyConstructor(int size, Map<String, String> paramMap, List<Integer> brandIds) {
  19 + super();
  20 + this.size = size;
  21 + this.paramMap = paramMap;
  22 + this.brandIds = brandIds;
  23 + }
  24 +
  25 + public int getSize() {
  26 + return size;
  27 + }
  28 + public Map<String, String> getParamMap() {
  29 + return paramMap;
  30 + }
  31 + public List<Integer> getBrandIds() {
  32 + return brandIds;
  33 + }
  34 +
  35 +
  36 +
  37 +
  38 +}
@@ -49,7 +49,7 @@ search.open.downgrade=true @@ -49,7 +49,7 @@ search.open.downgrade=true
49 49
50 50
51 #zkAddress 51 #zkAddress
52 -zkAddress=192.168.102.211:2181 52 +zkAddress=192.168.102.216:2181
53 53
54 #web.content 54 #web.content
55 web.context=yohosearch 55 web.context=yohosearch