Authored by hugufei

品类价格带添加AB测试

@@ -55,7 +55,7 @@ public class UserRecallResponseBuilder { @@ -55,7 +55,7 @@ public class UserRecallResponseBuilder {
55 sknResultList = this.fillBaseInfo(sknResultList); 55 sknResultList = this.fillBaseInfo(sknResultList);
56 56
57 //4、填充是否满足品类价格带的过滤 57 //4、填充是否满足品类价格带的过滤
58 - sknResultList = this.fillIsLikePriceArea(sknResultList, userPersonalFactor); 58 + sknResultList = this.fillIsLikePriceArea(userRecallRequest.getUid(),sknResultList, userPersonalFactor);
59 59
60 //5、按相关性计算得分 60 //5、按相关性计算得分
61 sknResultList = this.doCalScoreAndSort(sknResultList, userRecallRequest.getUid()); 61 sknResultList = this.doCalScoreAndSort(sknResultList, userRecallRequest.getUid());
@@ -130,7 +130,7 @@ public class UserRecallResponseBuilder { @@ -130,7 +130,7 @@ public class UserRecallResponseBuilder {
130 * @param sknResults 130 * @param sknResults
131 * @return 131 * @return
132 */ 132 */
133 - private List<RecallMergerResult.SknResult> fillIsLikePriceArea(List<RecallMergerResult.SknResult> sknResults, UserPersonalFactor userPersonalFactor) { 133 + private List<RecallMergerResult.SknResult> fillIsLikePriceArea(int uid, List<RecallMergerResult.SknResult> sknResults, UserPersonalFactor userPersonalFactor) {
134 //1、获取用户价格带偏好 134 //1、获取用户价格带偏好
135 List<SortPriceAreas> userSortPriceAreasList = userPersonalFactor.getSortPriceAreasList(); 135 List<SortPriceAreas> userSortPriceAreasList = userPersonalFactor.getSortPriceAreasList();
136 if (userSortPriceAreasList == null || userSortPriceAreasList.isEmpty()) { 136 if (userSortPriceAreasList == null || userSortPriceAreasList.isEmpty()) {
@@ -144,16 +144,67 @@ public class UserRecallResponseBuilder { @@ -144,16 +144,67 @@ public class UserRecallResponseBuilder {
144 //3、填充当前skn是否属于用户偏好的价格带 144 //3、填充当前skn是否属于用户偏好的价格带
145 for (RecallMergerResult.SknResult sknResult : sknResults) { 145 for (RecallMergerResult.SknResult sknResult : sknResults) {
146 Integer misortId = sknResult.getMiddleSortId(); 146 Integer misortId = sknResult.getMiddleSortId();
147 - List<Integer> priceAreas = userMisort2PriceAreasMap.getOrDefault(misortId, new ArrayList<>());  
148 - if (priceAreas.contains(sknResult.getPriceArea())) {  
149 - sknResult.setLikePriceArea(true);  
150 - } else {  
151 - sknResult.setLikePriceArea(false);  
152 - } 147 + List<Integer> userPriceAreas = userMisort2PriceAreasMap.getOrDefault(misortId, new ArrayList<>());
  148 + boolean isLikePriceArea = this.isLikePriceArea(uid,userPriceAreas,sknResult.getPriceArea());
  149 + sknResult.setLikePriceArea(isLikePriceArea);
153 } 150 }
154 return sknResults; 151 return sknResults;
155 } 152 }
156 153
  154 + /**
  155 + * AB test
  156 + * @param uid
  157 + * @param userPriceAreas
  158 + * @param sknPriceArea
  159 + * @return
  160 + */
  161 + private boolean isLikePriceArea(int uid, List<Integer> userPriceAreas,Integer sknPriceArea){
  162 + if(userPriceAreas==null || userPriceAreas.isEmpty()){
  163 + return false;
  164 + }
  165 + if(uid%2==1){
  166 + if(searchDynamicConfigService.isAStrategyOpen()){
  167 + return isLikePriceAreaWithAStrategy(userPriceAreas,sknPriceArea);
  168 + }else{
  169 + return isLikePriceAreaWithBStrategy(userPriceAreas,sknPriceArea);
  170 + }
  171 + }else{
  172 + if(searchDynamicConfigService.isBStrategyOpen()){
  173 + return isLikePriceAreaWithBStrategy(userPriceAreas,sknPriceArea);
  174 + }else{
  175 + return isLikePriceAreaWithAStrategy(userPriceAreas,sknPriceArea);
  176 + }
  177 + }
  178 + }
  179 +
  180 + private boolean isLikePriceAreaWithAStrategy(List<Integer> userPriceAreas,Integer sknPriceArea){
  181 + return userPriceAreas.contains(sknPriceArea);
  182 + }
  183 +
  184 + /**
  185 + * 价格带左右各扩展一位
  186 + * @param userPriceAreas
  187 + * @param sknPriceArea
  188 + * @return
  189 + */
  190 + private boolean isLikePriceAreaWithBStrategy(List<Integer> userPriceAreas,Integer sknPriceArea){
  191 + Collections.sort(userPriceAreas);
  192 + int min = userPriceAreas.get(0);
  193 + int max = userPriceAreas.get(userPriceAreas.size()-1);
  194 + int leftCount = min<=1 ? 0 : max>=7 ? 2 : 1;
  195 + int rightCount = min<=1 ? 2 : max>=7 ? 0 : 1;
  196 + for(int i = 1;i<=leftCount;i++){
  197 + if(min-i>=1){
  198 + userPriceAreas.add(0,min-i);
  199 + }
  200 + }
  201 + for(int i = 1;i<=rightCount;i++){
  202 + if(max+i<=7){
  203 + userPriceAreas.add(max+i);
  204 + }
  205 + }
  206 + return userPriceAreas.contains(sknPriceArea);
  207 + }
157 208
158 /** 209 /**
159 * 粗排-按相关性计算得分,并按得分排序 210 * 粗排-按相关性计算得分,并按得分排序
@@ -304,24 +355,24 @@ public class UserRecallResponseBuilder { @@ -304,24 +355,24 @@ public class UserRecallResponseBuilder {
304 } 355 }
305 356
306 public static void main(String[] args) { 357 public static void main(String[] args) {
307 - List<Integer> fromList = new ArrayList<>();  
308 - for (int index =1;index <=30;index ++){  
309 - fromList.add(index); 358 + List<Integer> userPriceAreas = new ArrayList<>();
  359 + userPriceAreas.addAll(Arrays.asList(5,6,7));
  360 + Collections.sort(userPriceAreas);
  361 + int min = userPriceAreas.get(0);
  362 + int max = userPriceAreas.get(userPriceAreas.size()-1);
  363 + int leftCount = min<=1 ? 0 : max>=7 ? 2 : 1;
  364 + int rightCount = min<=1 ? 2 : max>=7 ? 0 : 1;
  365 + for(int i = 1;i<=leftCount;i++){
  366 + if(min-i>=1){
  367 + userPriceAreas.add(0,min-i);
310 } 368 }
311 -  
312 - List<Integer> toList = new ArrayList<>();  
313 - for (int index =0;index <100;index ++){  
314 - toList.add(0);  
315 } 369 }
316 - addByIndexIndex(fromList, toList, 1, 2, (value -> value%2==1),null);  
317 -  
318 - addByIndexIndex(fromList, toList, 2, 3, (value -> value%2==0),null);  
319 -  
320 - System.out.println(toList);  
321 -// addByIndexIndex(fromList, toList, 4, 4, (value -> value%2==0));  
322 -// System.out.println(toList); 370 + for(int i = 1;i<=rightCount;i++){
  371 + if(max+i<=7){
  372 + userPriceAreas.add(max+i);
  373 + }
  374 + }
  375 + System.out.println(userPriceAreas);
323 } 376 }
324 -  
325 -  
326 377
327 } 378 }
@@ -48,8 +48,6 @@ public class SknRecallCacheBean { @@ -48,8 +48,6 @@ public class SknRecallCacheBean {
48 private SearchRedis searchRedis; 48 private SearchRedis searchRedis;
49 @Autowired 49 @Autowired
50 private EhCache ehCache; 50 private EhCache ehCache;
51 - @Autowired  
52 - private SearchDynamicConfigService searchDynamicConfigService;  
53 51
54 private static final Boolean recallWithCache = false; 52 private static final Boolean recallWithCache = false;
55 53
@@ -66,7 +64,7 @@ public class SknRecallCacheBean { @@ -66,7 +64,7 @@ public class SknRecallCacheBean {
66 filterSknList.addAll(userPersonalFactor.getRecommendSknList()); 64 filterSknList.addAll(userPersonalFactor.getRecommendSknList());
67 } 65 }
68 //1.1添加AB-Test逻辑 66 //1.1添加AB-Test逻辑
69 - if (searchDynamicConfigService.isAbTestUser(userRecallRequest.getUid()) && userPersonalFactor.getRealTimeSimilarSknList() != null) { 67 + if (userPersonalFactor.getRecommendSknList() != null) {
70 filterSknList.addAll(userPersonalFactor.getRealTimeSimilarSknList()); 68 filterSknList.addAll(userPersonalFactor.getRealTimeSimilarSknList());
71 } 69 }
72 //2、执行查询 70 //2、执行查询
@@ -80,9 +78,7 @@ public class SknRecallCacheBean { @@ -80,9 +78,7 @@ public class SknRecallCacheBean {
80 List<RecallRequestResponse> results = new ArrayList<>(); 78 List<RecallRequestResponse> results = new ArrayList<>();
81 ParamQueryFilter paramQueryFilter = userRecallRequest.getParamQueryFilter(); 79 ParamQueryFilter paramQueryFilter = userRecallRequest.getParamQueryFilter();
82 results.addAll(this.buildResults(paramQueryFilter, userPersonalFactor.getRecommendSknList(), RecommendSknStrategy.class, filterSknResults, maxReturnCount)); 80 results.addAll(this.buildResults(paramQueryFilter, userPersonalFactor.getRecommendSknList(), RecommendSknStrategy.class, filterSknResults, maxReturnCount));
83 - if(searchDynamicConfigService.isAbTestUser(userRecallRequest.getUid())){  
84 results.addAll(this.buildResults(paramQueryFilter, userPersonalFactor.getRealTimeSimilarSknList(), RealTimeSimilarSknStrategy.class, filterSknResults, maxReturnCount)); 81 results.addAll(this.buildResults(paramQueryFilter, userPersonalFactor.getRealTimeSimilarSknList(), RealTimeSimilarSknStrategy.class, filterSknResults, maxReturnCount));
85 - }  
86 return results; 82 return results;
87 } catch (Exception e) { 83 } catch (Exception e) {
88 RECALL_NEW_LOGGER.error(e.getMessage(), e); 84 RECALL_NEW_LOGGER.error(e.getMessage(), e);
@@ -242,18 +242,19 @@ public class SearchDynamicConfigService { @@ -242,18 +242,19 @@ public class SearchDynamicConfigService {
242 } 242 }
243 243
244 /** 244 /**
245 - * 奇数的uid使用AB-TEST 245 + * A策略是否打开
246 * @return 246 * @return
247 */ 247 */
248 - public boolean isAbTestUser(int uid) {  
249 - boolean abTestOpen = configReader.getBoolean("search.persional.abTest.open", false);  
250 - if(!abTestOpen){  
251 - return true; 248 + public boolean isAStrategyOpen() {
  249 + return configReader.getBoolean("search.persional.abTest.a.strategy.open", true);
252 } 250 }
253 - if(uid%2==1){  
254 - return true;  
255 - }  
256 - return false; 251 +
  252 + /**
  253 + * B策略是否打开
  254 + * @return
  255 + */
  256 + public boolean isBStrategyOpen() {
  257 + return configReader.getBoolean("search.persional.abTest.b.strategy.open", true);
257 } 258 }
258 259
259 } 260 }
@@ -62,7 +62,8 @@ search.persional.newstrategy.max_join_sort_brand.count=20 @@ -62,7 +62,8 @@ search.persional.newstrategy.max_join_sort_brand.count=20
62 search.persional.newstrategy.directtrain.index.interval=4 62 search.persional.newstrategy.directtrain.index.interval=4
63 63
64 search.persional.newstrategy.sort_brand_balance.open=false 64 search.persional.newstrategy.sort_brand_balance.open=false
65 -search.persional.abTest.open=true 65 +search.persional.abTest.a.strategy.open=true
  66 +search.persional.abTest.b.strategy.open=true
66 67
67 #rateLimit 68 #rateLimit
68 search.persional.rateLimit.open=true 69 search.persional.rateLimit.open=true