Authored by hugufei

A/B用户品类资源位直通车可动态开关

... ... @@ -4,15 +4,12 @@ import com.yoho.core.config.ConfigReader;
import com.yoho.search.aop.downgrade.PersionalRateLimit;
import com.yoho.search.aop.downgrade.PersionalRateLimitConfig;
import com.yoho.search.base.utils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Service
... ... @@ -23,36 +20,6 @@ public class SearchDynamicConfigService {
@Autowired
private ConfigReader configReader;
private List<String> ufoWholeFirstSearchKeyWords = new ArrayList<>();
private List<String> ufoPartFirstSearchKeyWords = new ArrayList<>();
@PostConstruct
void init(){
//完全匹配
ufoWholeFirstSearchKeyWords.addAll(Arrays.asList("喷"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("冠军"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("椰子","yeezy"));
//部分包含
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("nike","耐克"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("adidas","originals","三叶草","阿迪","阿迪达斯"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("ow","off-white"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("亚限","欧限","美限"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("太极","飞马","倒勾","湖人","黑粉"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("aj", "air","max","force","pg","m2k","gs","supreme","af1"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("90","95","97","98","720","350", "500", "700"));
//20190828新增
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("满天星","詹姆斯","天使","哈登","蜘蛛侠","宝可梦","丝绸","亚洲","鸳鸯","阴阳"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("芝加哥","小闪电","子弹","sb","小花","蓝蛇","字母哥","小黑金","欧洲","凯尔特人"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("白斑马","万花筒","黑曜石","上海","union","芝麻","禁止","宇航员","四色鸳鸯","银子弹"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("彩虹","阿甘","遛狗","解构","鸽子","闪电","子弹头","灯芯绒","黑武士","艾弗森"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("钢铁侠","pg1","龙虾","首尔","笑脸","白冰淇淋","万圣节","海军蓝","冰淇淋","大理石"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("独角兽","大巴黎","做旧","af","要疯","黑魂","小麦","迈阿密限定","荔枝纹","绑带"));
ufoPartFirstSearchKeyWords.addAll(Arrays.asList("熊猫","迷宫","马毛","骑士","纯白","黑曜石","慈善","透视骨骼","夜光骨头"));
}
/**
* 是否开启个性化
*/
... ... @@ -240,25 +207,6 @@ public class SearchDynamicConfigService {
}
/**
* ufo商品在前面的特殊搜索词
*/
public boolean ufoProductFirstBySearchKeyWord(String query) {
if(StringUtils.isBlank(query)){
return false;
}
String queryLowerCase = query.toLowerCase();
if(this.ufoWholeFirstSearchKeyWords.contains(queryLowerCase)){
return true;
}
for(String ufoPartFirstSearchKeyWord:this.ufoPartFirstSearchKeyWords){
if(queryLowerCase.contains(ufoPartFirstSearchKeyWord)){
return true;
}
}
return false;
}
/**
* 新品天数
*/
public int newProductDayCount() {
... ... @@ -277,4 +225,12 @@ public class SearchDynamicConfigService {
}
}
public boolean sortSearchResourceAUserOpen() {
return configReader.getBoolean("search.sort.resource.a.open", true);
}
public boolean sortSearchResourceBUserOpen() {
return configReader.getBoolean("search.sort.resource.b.open", false);
}
}
... ...
package com.yoho.search.common.utils;
import com.yoho.search.common.SearchDynamicConfigService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
@Component
public class ABUserPartitionUtils {
private static final Logger logger = LoggerFactory.getLogger(ABUserPartitionUtils.class);
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
private boolean isAUser(String udid) {
if (StringUtils.isBlank(udid)) {
return false;
}
List<String> aStrategyUdIds = searchDynamicConfigService.aStrategyUdIds();
if (aStrategyUdIds.contains(udid)) {
public boolean isAUserComplete(int uid, String udid) {
try {
List<Integer> aStrategyUIds = searchDynamicConfigService.aStrategyUIds();
if (aStrategyUIds.contains(uid)) {
return true;
}
if (StringUtils.isBlank(udid)) {
return false;
}
List<String> aStrategyUdIds = searchDynamicConfigService.aStrategyUdIds();
if (aStrategyUdIds.contains(udid)) {
return true;
}
int tail = Math.abs(udid.hashCode() % 1024);
int aUserPercent = searchDynamicConfigService.partAUserPercent();
int aUserFloor = 1024 * aUserPercent / 100;
return tail < aUserFloor ? true : false;
} catch (Exception e) {
logger.error(e.getMessage(), e);
return true;
}
int tail = Math.abs(udid.hashCode() % 1024);
int aUserPercent = searchDynamicConfigService.partAUserPercent();
int aUserFloor = 1024 * aUserPercent / 100;
return tail < aUserFloor ? true : false;
}
public boolean isAUserComplete(int uid, String udid) {
List<Integer> aStrategyUIds = searchDynamicConfigService.aStrategyUIds();
if (aStrategyUIds.contains(uid)) {
return true;
}
return isAUser(udid);
public boolean isAUserComplete(Map<String, String> paramMap) {
int uid = MapUtils.getIntValue(paramMap, "uid", 0);
String udid = MapUtils.getString(paramMap, "udid", "");
return isAUserComplete(uid, udid);
}
public static void main(String[] args) {
// System.out.println(isAUserComplete(13420925, "f6ec847d5ac7ce275992db526666e997eb39425a"));//A版本
// System.out.println(isAUserComplete(13420925, "00bcfa1e5d7745ad8c4188929134da18f8485dbd"));//B版本
int aUserFloor = 1024 * 49 / 100;
System.out.println( aUserFloor);
System.out.println(aUserFloor);
}
}
... ...
... ... @@ -3,6 +3,8 @@ package com.yoho.search.service.scene.general;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ConvertUtils;
import com.yoho.search.base.utils.SearchCollectionUtils;
import com.yoho.search.common.SearchDynamicConfigService;
import com.yoho.search.common.utils.ABUserPartitionUtils;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.index.CsSearchResourceIndexBaseService;
import org.apache.commons.collections.MapUtils;
... ... @@ -27,10 +29,24 @@ public class CsSearchResourceService {
private CsSearchResourceIndexBaseService csSearchResourceIndexBaseService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private ABUserPartitionUtils abUserPartitionUtils;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
//处理品类页的资源位直通车
public List<Map<String, Object>> querySortSearchResource(JSONObject productListData, Map<String, String> paramMap) {
try {
//0、判断是否开启
if(abUserPartitionUtils.isAUserComplete(paramMap)){
if(!searchDynamicConfigService.sortSearchResourceAUserOpen()){
return new ArrayList<>();
}
}else{
if(!searchDynamicConfigService.sortSearchResourceBUserOpen()){
return new ArrayList<>();
}
}
//1、获取全部销售类型的数据
List<Map<String, Object>> allValidResources = csSearchResourceIndexBaseService.querySalesCategoryCsSearchResource();
... ...
... ... @@ -75,22 +75,6 @@ public class SearchScorerFactory {
}
}
// 获取【UFO商品】的打分器
public IScorer getUfoProductSearch(Map<String, String> paramMap) {
if (!searchCommonHelper.containUFO(paramMap)) {
return null;
}
if (!searchCommonHelper.isFuzzySearchPageDefault(paramMap)) {
return null;
}
String query = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY, "");
if (dynamicConfig.ufoProductFirstBySearchKeyWord(query)) {
return new UfoProductScorer(20f);
} else {
return null;
}
}
// // 获取【断码商品】的打分器
// public IScorer getBreakSizeProductScorer(Map<String, String> paramMap) {
// try {
... ...
... ... @@ -75,5 +75,6 @@ search.agg.brand.product.new=true
search.productlist.return.goods=true
search.ufo.contain.yoho=true
search.newProduct.dayCount=7
search.ufo.productName.prefixType=b
search.ufo.forbidden.entrace.brandIds=
search.sort.resource.a.open=true
search.sort.resource.b.open=false
... ...