Authored by hugufei

列表相关代码拆包

Showing 32 changed files with 565 additions and 749 deletions
... ... @@ -2,26 +2,19 @@ package com.yoho.search.recall.common;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.CacheType;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.core.personalized.PersonalizedSearch;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.recall.common.beans.ProductFeatureFactorHepler;
import com.yoho.search.recall.common.cacheable.CacheAbleServiceHelper;
import com.yoho.search.recall.common.cacheable.CommonPageRecallService;
import com.yoho.search.recall.common.model.CommonRecallParam;
import com.yoho.search.recall.common.model.CommonRecallResult;
import com.yoho.search.recall.common.model.CommonRecallSkn;
import com.yoho.search.recall.common.model.UserFeatureFactor;
import com.yoho.search.service.base.ProductListSortKey;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
import com.yoho.search.service.scorer.personal.PersonalVectorFeatureSearch;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
... ... @@ -33,233 +26,165 @@ import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Component;
import java.util.*;
@Service
public class ProductListServiceHelper {
@Component
public class CommonRecallProductListService {
private static final Logger logger = LoggerFactory.getLogger(ProductListServiceHelper.class);
private static final Logger logger = LoggerFactory.getLogger(CommonRecallProductListService.class);
@Autowired
private CommonPageRecallService commonRecallSceneService;
@Autowired
private ProductListSortService productListSortService;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private SearchSortHelper searchSortHelper;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private PersonalVectorFeatureSearch personalVectorFeatureSearch;
@Autowired
private ProductFeatureFactorHepler productFeatureFactorHepler;
@Autowired
private CacheAbleServiceHelper cacheAbleServiceHelper;
@Autowired
private CommonPageRecallService commonRecallSceneService;
@Autowired
private PersonalVectorFeatureSearch personalVectorFeatureSearch;
@Autowired
private ProductFeatureFactorHepler productFeatureFactorHepler;
@Autowired
private CacheAbleServiceHelper cacheAbleServiceHelper;
@Autowired
private ProductListSortService productListSortService;
/**
* 个性化的列表接口
*
* @order为空并且有uid
* @param paramMap
* @return
*/
public SearchApiResult productListForNewPersional(Map<String, String> paramMap) {
// 1、召回整数页个skn[需要new一个对象出来,不然原有数据的顺序会变]
CommonRecallResult cacheObject = commonRecallSceneService.doCommonPageRecallBatch(paramMap);
CommonRecallResult commonRecallResult = new CommonRecallResult(cacheObject);
// 2、获取分页参数
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
int viewNum = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
long total = commonRecallResult.getTotalCount();
// 3、为用户做列表截取-保留第一页数据
int recallMaxPage = (int) (commonRecallResult.listCount() / viewNum);
if (recallMaxPage == 0) {
recallMaxPage = 1;
}
// 4、构造分页结果参数
JSONObject results = new JSONObject();
results.put("total", total);
results.put("page", page);
results.put("page_size", viewNum);
results.put("page_total", this.getTotalPage(total, viewNum));
// 5、构造productList
if (page <= recallMaxPage) {
results.put("product_list", this.queryProductListForPersional(commonRecallResult, paramMap, page, viewNum));
} else {
results.put("product_list", this.queryProductListForOtherPageIndex(paramMap, commonRecallResult, page - recallMaxPage, viewNum).getData());
}
return new SearchApiResult().setData(results);
}
/**
* 高性能的个性化的列表接口
*
* @order为空并且有uid
* @param paramMap
* @return
*/
public SearchApiResult productList(Map<String, String> paramMap) {
// 1、召回整数页个skn[需要new一个对象出来,不然原有数据的顺序会变]
CommonRecallResult cacheObject = commonRecallSceneService.doCommonPageRecallBatch(paramMap);
CommonRecallResult commonRecallResult = new CommonRecallResult(cacheObject);
// 2、获取分页参数
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
int viewNum = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
long total = commonRecallResult.getTotalCount();
// 3、为用户做列表截取-保留第一页数据
int recallMaxPage = (int) (commonRecallResult.listCount() / viewNum);
if (recallMaxPage == 0) {
recallMaxPage = 1;
}
// 4、构造分页结果参数
JSONObject results = new JSONObject();
results.put("total", total);
results.put("page", page);
results.put("page_size", viewNum);
results.put("page_total", this.getTotalPage(total, viewNum));
// 5、构造productList
if (page <= recallMaxPage) {
results.put("product_list", this.queryProductListForPersional(commonRecallResult, paramMap, page, viewNum));
} else {
results.put("product_list", this.queryProductListForOtherPageIndex(paramMap, commonRecallResult, page - recallMaxPage, viewNum).getData());
}
return new SearchApiResult().setData(results);
}
/**
* 召回页的处理方式
*
* @param commonRecallResult
* @param page
* @param viewNum
* @return
*/
private List<? extends Map<?, ?>> queryProductListForPersional(CommonRecallResult commonRecallResult, Map<String, String> paramMap, int page, int viewNum) {
// 1、查询这整数页个skn的全部信息-包含了变价计划[在排序前查询才能命中缓存!~]
SearchApiResult productInfoMapResult = cacheAbleServiceHelper.queryProductInfoMap(commonRecallResult);
// 2、排序
commonRecallResult = this.callUserScoreAndRank(paramMap, commonRecallResult);
// 3、数量截取
JSONObject productInfoMap = (JSONObject) productInfoMapResult.getData();
List<JSONObject> results = new ArrayList<JSONObject>();
List<CommonRecallSkn> recallSknList = commonRecallResult.getRecallSknList();
int fromIndex = (page - 1) * viewNum;
int toIndex = page * viewNum;
if (toIndex > recallSknList.size()) {
toIndex = recallSknList.size();
}
recallSknList = CollectionUtils.safeSubList(recallSknList, fromIndex, toIndex);
for (CommonRecallSkn commonRecallSkn : recallSknList) {
results.add(productInfoMap.getJSONObject(String.valueOf(commonRecallSkn.getProductSkn())));
}
// 4、品牌打散
results = productListSortService.sortProductList(results, new ProductListSortKey<JSONObject>() {
@Override
public String getSortKey(JSONObject product) {
return MapUtils.getString(product, "brand_id", "0");
}
@Override
public int getMaxCount() {
return 2;
}
});
return results;
}
/**
* 召回页的处理方式
*
* @param commonRecallResult
* @param page
* @param viewNum
* @return
*/
private List<? extends Map<?, ?>> queryProductListForPersional(CommonRecallResult commonRecallResult, Map<String, String> paramMap, int page, int viewNum) {
// 1、查询这整数页个skn的全部信息-包含了变价计划[在排序前查询才能命中缓存!~]
SearchApiResult productInfoMapResult = cacheAbleServiceHelper.queryProductInfoMap(commonRecallResult);
// 2、排序
commonRecallResult = this.callUserScoreAndRank(paramMap, commonRecallResult);
// 3、数量截取
JSONObject productInfoMap = (JSONObject) productInfoMapResult.getData();
List<JSONObject> results = new ArrayList<JSONObject>();
List<CommonRecallSkn> recallSknList = commonRecallResult.getRecallSknList();
int fromIndex = (page - 1) * viewNum;
int toIndex = page * viewNum;
if (toIndex > recallSknList.size()) {
toIndex = recallSknList.size();
}
recallSknList = CollectionUtils.safeSubList(recallSknList, fromIndex, toIndex);
for (CommonRecallSkn commonRecallSkn : recallSknList) {
results.add(productInfoMap.getJSONObject(String.valueOf(commonRecallSkn.getProductSkn())));
}
// 4、品牌打散
results = productListSortService.sortProductList(results, new ProductListSortKey<JSONObject>() {
@Override
public String getSortKey(JSONObject product) {
return MapUtils.getString(product, "brand_id", "0");
}
@Override
public int getMaxCount() {
return 2;
}
});
return results;
}
/**
* 其他页码的处理方式
*
* @param paramMap
* @param commonRecallResult
* @param realPage
* @return
*/
private SearchApiResult queryProductListForOtherPageIndex(Map<String, String> paramMap, CommonRecallResult commonRecallResult, int realPage, int viewNum) {
try {
// 1、其他页码使用CommonRecallParamService去查询
CommonRecallParam commonRecallParam = new CommonRecallParam(paramMap, 0, realPage, viewNum);
// 2、前面几个已经召回的需要排除
BoolQueryBuilder extendMustFilter = QueryBuilders.boolQuery();
extendMustFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, commonRecallResult.toSknList()));
commonRecallParam.setExtendMustFilter(extendMustFilter);
// 3、构造sort
List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.sevendayMoney).order(SortOrder.DESC));
commonRecallParam.setSortBuilders(sortBuilders);
// 4、执行查询
return cacheAbleServiceHelper.queryProductListByRecallParam(commonRecallParam);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(new ArrayList<>());
}
}
/**
* 其他页码的处理方式
*
* @param paramMap
* @param commonRecallResult
* @param realPage
* @return
*/
private SearchApiResult queryProductListForOtherPageIndex(Map<String, String> paramMap, CommonRecallResult commonRecallResult, int realPage, int viewNum) {
try {
// 1、其他页码使用CommonRecallParamService去查询
CommonRecallParam commonRecallParam = new CommonRecallParam(paramMap, 0, realPage, viewNum);
// 2、前面几个已经召回的需要排除
BoolQueryBuilder extendMustFilter = QueryBuilders.boolQuery();
extendMustFilter.mustNot(QueryBuilders.termsQuery(ProductIndexEsField.productSkn, commonRecallResult.toSknList()));
commonRecallParam.setExtendMustFilter(extendMustFilter);
// 3、构造sort
List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.sevendayMoney).order(SortOrder.DESC));
commonRecallParam.setSortBuilders(sortBuilders);
// 4、执行查询
return cacheAbleServiceHelper.queryProductListByRecallParam(commonRecallParam);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(new ArrayList<>());
}
}
private long getTotalPage(long total, int viewNum) {
if (viewNum == 0) {
return total;
}
long totalPage = total / viewNum;
if (total % viewNum > 0) {
totalPage = totalPage + 1;
}
return totalPage;
}
private long getTotalPage(long total, int viewNum) {
if (viewNum == 0) {
return total;
}
long totalPage = total / viewNum;
if (total % viewNum > 0) {
totalPage = totalPage + 1;
}
return totalPage;
}
/**
* 根据向量计算得分并排序
*
* @param paramMap
* @param commonRecallResult
* @return
*/
private CommonRecallResult callUserScoreAndRank(Map<String, String> paramMap, CommonRecallResult commonRecallResult) {
PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.getPersonalizedSearch(paramMap);
UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch);
List<String> firstProductSkns = Arrays.asList(MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_FIRST_PRODUCRSKN, "").split(","));
for (CommonRecallSkn commonRecallSkn : commonRecallResult.getRecallSknList()) {
if (firstProductSkns.contains(String.valueOf(commonRecallSkn.getProductSkn()))) {
commonRecallSkn.setScore(10000d);// firstSkn排第一个
} else {
commonRecallSkn.setScore(productFeatureFactorHepler.calProductFeatureFactor(userFeatureFactor, commonRecallSkn.getProductFeatureFactor()));
}
}
Collections.sort(commonRecallResult.getRecallSknList(), new Comparator<CommonRecallSkn>() {
@Override
public int compare(CommonRecallSkn o1, CommonRecallSkn o2) {
return o2.getScore().compareTo(o1.getScore());// 大的排前面
}
});
return commonRecallResult;
}
/**
* 非个性化的列表接口-去除uid缓存
*
* @order不为空,或者无uid
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "PRODUCT_LIST_NOT_PERSIONAL", cacheType = CacheType.SEARCH_REDIS, cacheInMinute = 10, excludeParams = { "uid", "firstProductSkn" })
public SearchApiResult productListNotPersional(Map<String, String> paramMap) {
return this.productList(paramMap);
}
/**
* 个性化的列表接口-基于向量的个性化缓存-估计命中率会很低
*
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "PRODUCT_LIST_DEFAULT_PERSIONAL", cacheType = CacheType.SEARCH_REDIS, cacheInMinute = 10)
public SearchApiResult productListForDefaultPersional(Map<String, String> paramMap) {
return this.productList(paramMap);
}
private SearchApiResult productList(Map<String, String> paramMap){
try {
// 1)验证查询条数
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0 || page * pageSize > 1000000) {
return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
}
if (pageSize > 100) {
pageSize = 100;
}
// 2)构建基本查询参数
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, true);// 这个必须用buildWithPersional构造,有些特殊的逻辑-如firstSkn在里面
searchParam.setAggregationBuilders(null);
searchParam.setOffset((page - 1) * pageSize);
searchParam.setSize(pageSize);
// 3)设置排序字段
searchParam.setSortBuilders(searchSortHelper.buildSortList(paramMap));
// 4)设置返回的参数【节省带宽】
List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
searchParam.setIncludeFields(includeFields);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
// 5)构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
dataMap.put("product_list", productListSortService.sortProductList(product_list));// 处理一下商品的顺序;
return new SearchApiResult().setData(dataMap);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setCode(500);
}
}
/**
* 根据向量计算得分并排序
*
* @param paramMap
* @param commonRecallResult
* @return
*/
private CommonRecallResult callUserScoreAndRank(Map<String, String> paramMap, CommonRecallResult commonRecallResult) {
PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.getPersonalizedSearch(paramMap);
UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch);
List<String> firstProductSkns = Arrays.asList(MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_FIRST_PRODUCRSKN, "").split(","));
for (CommonRecallSkn commonRecallSkn : commonRecallResult.getRecallSknList()) {
if (firstProductSkns.contains(String.valueOf(commonRecallSkn.getProductSkn()))) {
commonRecallSkn.setScore(10000d);// firstSkn排第一个
} else {
commonRecallSkn.setScore(productFeatureFactorHepler.calProductFeatureFactor(userFeatureFactor, commonRecallSkn.getProductFeatureFactor()));
}
}
Collections.sort(commonRecallResult.getRecallSknList(), new Comparator<CommonRecallSkn>() {
@Override
public int compare(CommonRecallSkn o1, CommonRecallSkn o2) {
return o2.getScore().compareTo(o1.getScore());// 大的排前面
}
});
return commonRecallResult;
}
}
... ...
package com.yoho.search.recall.common;
package com.yoho.search.recall.common.beans;
import java.util.ArrayList;
import java.util.Arrays;
... ...
package com.yoho.search.recall.common;
package com.yoho.search.recall.common.beans;
import com.yoho.search.recall.common.model.UserFeatureFactor;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.yoho.search.core.personalized.PersonalizedSearch;
@Component
public class ProductFeatureFactorHepler {
... ... @@ -15,7 +14,7 @@ public class ProductFeatureFactorHepler {
private static double baseConstant = 1;
private static double factorConstant = 1;
public double calProductFeatureFactor(UserFeatureFactor userFeatureFactor,String productFeatureFactor){
public double calProductFeatureFactor(UserFeatureFactor userFeatureFactor, String productFeatureFactor){
try {
//用户向量不存在,则直接随机
if(userFeatureFactor==null || StringUtils.isBlank(userFeatureFactor.vectorFeatureVersion)){
... ...
package com.yoho.search.recall.common.cacheable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.CacheType;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.recall.common.beans.BaseRecallService;
import com.yoho.search.recall.common.model.CommonRecallResult;
import com.yoho.search.recall.common.model.CommonRecallSkn;
import com.yoho.search.service.base.SearchRequestParams;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
... ... @@ -15,23 +22,11 @@ import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.common.cache.CacheType;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchSortHelper;
import com.yoho.search.recall.common.BaseRecallService;
import com.yoho.search.recall.common.model.CommonRecallResult;
import com.yoho.search.recall.common.model.CommonRecallSkn;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@Component
public class CommonPageRecallService extends BaseRecallService {
... ...
package com.yoho.search.recall.common;
package com.yoho.search.recall.common.model;
import com.yoho.search.core.personalized.PersonalizedSearch;
... ...
... ... @@ -30,9 +30,9 @@ import java.util.List;
import java.util.Map;
@Component
public class NewSceneRecallService {
public class SceneRecallProductListService {
private static final Logger logger = LoggerFactory.getLogger(NewSceneRecallService.class);
private static final Logger logger = LoggerFactory.getLogger(SceneRecallProductListService.class);
@Autowired
private RecallParamsBuilder recallParamsBuilder;
... ... @@ -45,7 +45,7 @@ public class NewSceneRecallService {
@Autowired
private QueryProductInfoCacheBean queryProductInfoCacheBean;
public SearchApiResult sceneRecall(Map<String, String> paramMap) {
public SearchApiResult productList(Map<String, String> paramMap) {
try {
//1、分页参数验证
int page = MapUtils.getIntValue(paramMap, "page", 1);
... ...
... ... @@ -21,7 +21,7 @@ import org.springframework.stereotype.Service;
import java.util.*;
@Service
public class SortRecallSceneService extends AbstractRecallService {
public class SortRecallProductListService extends AbstractRecallService {
@Autowired
private ProductListSortService productListSortService;
... ...
package com.yoho.search.restapi;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.press.PressTestService;
@Controller
public class PressTestController {
@Autowired
private PressTestService pressTestService;
@RequestMapping(method = RequestMethod.GET, value = "/pressProductIndex")
@ResponseBody
public SearchApiResult pressProductIndex(String brandIds, String smallSortIds, int size, String order, boolean withRange) {
return pressTestService.pressProductIndex(brandIds, smallSortIds, size, order, withRange);
}
@RequestMapping(method = RequestMethod.GET, value = "/pressProductBaseIndex")
@ResponseBody
public SearchApiResult pressProductBaseIndex(String brandIds, String smallSortIds, int size, String order, boolean withRange) {
return pressTestService.pressProductBaseIndex(brandIds, smallSortIds, size, order, withRange);
}
}
... ... @@ -16,7 +16,7 @@ import com.alibaba.fastjson.JSONObject;
import com.yoho.search.common.downgrade.persional.PersionalRateLimit;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.service.IProductListService;
@Controller
... ... @@ -25,7 +25,7 @@ public class ProductListController {
@Autowired
private IProductListService productListService;
@Autowired
private CommonSceneProductListService commonSceneProductListService;
private ProductListSwitchService productListSwitchService;
/**
* 获取商品列表-支持个性化降级
... ... @@ -37,7 +37,7 @@ public class ProductListController {
@ResponseBody
public SearchApiResult productList(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return commonSceneProductListService.productList(paramMap);
return productListSwitchService.productList(paramMap);
}
/**
... ... @@ -50,7 +50,7 @@ public class ProductListController {
public SearchApiResult productListByPost(@RequestBody JSONObject param) {
Map<String, String> paramMap = this.getParamMap(param);
paramMap.remove("uid");
return commonSceneProductListService.productList(paramMap);
return productListSwitchService.productList(paramMap);
}
/**
... ...
package com.yoho.search.restapi;
import com.yoho.search.common.utils.HttpServletRequestUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.recall.scene.NewSceneRecallService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
public class SceneRecallTestController {
@Autowired
private NewSceneRecallService newSceneRecallService;
/**
* 获取品牌列表[不包含全球购]
*
* @param request
* @return
*/
@RequestMapping(method = RequestMethod.GET, value = "/sceneRecall")
@ResponseBody
public SearchApiResult sceneRecall(HttpServletRequest request) {
Map<String, String> paramMap = HttpServletRequestUtils.transParamType(request);
return newSceneRecallService.sceneRecall(paramMap);
}
}
package com.yoho.search.restapi.scene;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.common.downgrade.persional.PersionalRateLimit;
import com.yoho.search.models.PromotionConditions;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.promotion.PromotionSceneService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -12,12 +15,8 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.common.downgrade.persional.PersionalRateLimit;
import com.yoho.search.models.PromotionConditions;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.promotion.PromotionSceneService;
import java.util.HashMap;
import java.util.Map;
/**
* 商品详情页的促销列表接口
... ... @@ -36,9 +35,6 @@ public class PromotionSceneController {
/**
* 促销列表接口[新]
*
* @param request
* @return
*/
@PersionalRateLimit(isOrderUseable = true)
@RequestMapping(method = RequestMethod.POST, value = "/promotion/productList")
... ... @@ -57,9 +53,6 @@ public class PromotionSceneController {
/**
* 促销列表接口[旧]
*
* @param request
* @return
*/
@PersionalRateLimit(isOrderUseable = true, name = "/promotion/productList")
@RequestMapping(method = RequestMethod.POST, value = "/promotion/list")
... ... @@ -78,9 +71,6 @@ public class PromotionSceneController {
/**
* 促销列表接口[新]
*
* @param request
* @return
*/
@PersionalRateLimit(isOrderUseable = false)
@RequestMapping(method = RequestMethod.POST, value = "/promotion/aggregations")
... ... @@ -99,9 +89,6 @@ public class PromotionSceneController {
/**
* 促销聚合接口[for app]
*
* @param request
* @return
*/
@RequestMapping(method = RequestMethod.POST, value = "/promotion/selectionsForApp")
@ResponseBody
... ... @@ -119,9 +106,6 @@ public class PromotionSceneController {
/**
* 促销聚合接口[for pc]
*
* @param request
* @return
*/
@RequestMapping(method = RequestMethod.POST, value = "/promotion/selectionsForPc")
@ResponseBody
... ... @@ -139,8 +123,6 @@ public class PromotionSceneController {
/**
* 促销聚合品牌的接口
*
* @param request
* @return
*/
@RequestMapping(method = RequestMethod.POST, value = "/promotion/aggBrands")
... ...
... ... @@ -20,13 +20,10 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.utils.SearchParamUtils;
import com.yoho.search.recall.sort.SortRecallSceneService;
import com.yoho.search.recall.sort.SortRecallProductListService;
@Controller
public class TestDslController {
@Autowired
private SortRecallSceneService sortRecallSceneService;
@RequestMapping(method = RequestMethod.GET, value = "/testDsl")
@ResponseBody
... ...
... ... @@ -15,7 +15,7 @@ import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.common.cache.impls.EhCache;
import com.yoho.search.common.cache.model.CacheObject;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
@Controller
public class TestEhcacheController {
... ... @@ -25,7 +25,7 @@ public class TestEhcacheController {
@Autowired
private EhCache ehCache;
@Autowired
private CommonSceneProductListService commonSceneProductListService;
private ProductListSwitchService productListSwitchService;
@RequestMapping(value = "/testEhcache/put")
... ... @@ -33,7 +33,7 @@ public class TestEhcacheController {
public Map<String, Object> testPut(int count,int viewNum) {
Map<String,String> paramMap = new HashMap<String, String>();
paramMap.put("viewNum", ""+viewNum);
JSONObject productList = (JSONObject)commonSceneProductListService.productList(paramMap).getData();
JSONObject productList = (JSONObject) productListSwitchService.productList(paramMap).getData();
for (int i=1;i<=count;i++) {
ehCache.addOrUpdate("Key"+i, new CacheObject(productList), 1);
}
... ...
... ... @@ -187,7 +187,7 @@ public class SearchDynamicConfigService {
}
/**
* 使用性能高的召回场景【双11打开】
* 使用新的的召回策略
*
* @return
*/
... ... @@ -196,6 +196,15 @@ public class SearchDynamicConfigService {
}
/**
* 使用性能高的召回场景【双11打开】
*
* @return
*/
public boolean searchPersionalPerfamanceStrategyOpen() {
return configReader.getBoolean("search.persional.performancestrategy.open", false);
}
/**
* 品类页使用新的召回机制-【双11关闭】
*/
public boolean isSortPageRecallOpen() {
... ...
package com.yoho.search.service.list;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.cache.CacheType;
import com.yoho.search.common.cache.aop.SearchCacheAble;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
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.Service;
import java.util.*;
@Service
public class DefaultProductListService {
private static final Logger logger = LoggerFactory.getLogger(DefaultProductListService.class);
@Autowired
private ProductListSortService productListSortService;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private SearchSortHelper searchSortHelper;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private SearchCommonService searchCommonService;
/**
* 个性化的列表接口-基于向量的个性化缓存-估计命中率会很低
*
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "PRODUCT_LIST_DEFAULT_PERSIONAL", cacheType = CacheType.SEARCH_REDIS, cacheInMinute = 10)
public SearchApiResult productListForDefaultPersional(Map<String, String> paramMap) {
return this.productList(paramMap);
}
/**
* 非个性化的列表接口-去除uid缓存
*
* @order不为空,或者无uid
* @param paramMap
* @return
*/
@SearchCacheAble(cacheName = "PRODUCT_LIST_NOT_PERSIONAL", cacheType = CacheType.SEARCH_REDIS, cacheInMinute = 10, excludeParams = { "uid", "firstProductSkn" })
public SearchApiResult productListNotPersional(Map<String, String> paramMap) {
return this.productList(paramMap);
}
private SearchApiResult productList(Map<String, String> paramMap){
try {
// 1)验证查询条数
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0 || page * pageSize > 1000000) {
return new SearchApiResult().setCode(400).setMessage("分页参数不合法");
}
if (pageSize > 100) {
pageSize = 100;
}
// 2)构建基本查询参数
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, true);// 这个必须用buildWithPersional构造,有些特殊的逻辑-如firstSkn在里面
searchParam.setAggregationBuilders(null);
searchParam.setOffset((page - 1) * pageSize);
searchParam.setSize(pageSize);
// 3)设置排序字段
searchParam.setSortBuilders(searchSortHelper.buildSortList(paramMap));
// 4)设置返回的参数【节省带宽】
List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
searchParam.setIncludeFields(includeFields);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
// 5)构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
dataMap.put("product_list", productListSortService.sortProductList(product_list));// 处理一下商品的顺序;
return new SearchApiResult().setData(dataMap);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setData(null).setCode(500);
}
}
}
... ...
package com.yoho.search.service.scene.common;
import java.util.List;
import java.util.Map;
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.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.cache.SearchCacheMatchLogger;
import com.yoho.search.common.cache.model.SearchCache;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
@Service
public class FuzzySceneProductListService extends AbstractCacheAbleService {
private static final Logger logger = LoggerFactory.getLogger(CommonSceneProductListService.class);
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private SearchSortHelper searchSortHelper;
@Autowired
private ProductListSortService productListSortService;
@Override
public SearchCache getSearchCache() {
return searchCacheFactory.getFuzzySearchCache();
}
/**
* 获取商品列表
*
* @param paramMap
* @return
* @throws Exception
*/
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 1)构造搜索参数
SearchParam searchParam = this.buildProductListSearchParam(paramMap);
// 2)从缓存中获取数据
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, indexName, searchParam);
if (cacheObject != null) {
SearchCacheMatchLogger.doSearchCacheMatchLog("/scene/productList.json", paramMap);
return new SearchApiResult().setData(cacheObject);
}
// 3)查询ES
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null) {
return new SearchApiResult().setCode(500).setMessage("execption");
}
// 4)构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
dataMap.put("product_list", productListSortService.sortProductList(product_list));// 处理一下商品的顺序;
// 5)将结果存进缓存
searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, dataMap);
return new SearchApiResult().setData(dataMap);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setCode(500).setMessage("scene productList exception").setData(new JSONObject());
}
}
private SearchParam buildProductListSearchParam(Map<String, String> paramMap) throws Exception {
// 1)验证查询条数
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0) {
throw new IllegalArgumentException("分页参数不合法");
}
if (pageSize > 100) {
pageSize = 100;
}
// 2)构建基本查询参数
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, true);
searchParam.setAggregationBuilders(null);
searchParam.setOffset((page - 1) * pageSize);
searchParam.setSize(pageSize);
// 3)设置排序字段
searchParam.setSortBuilders(searchSortHelper.buildSortList(paramMap));
// 4)设置返回的参数【节省带宽】
List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
searchParam.setIncludeFields(includeFields);
return searchParam;
}
}
package com.yoho.search.service.list;
import java.util.List;
import java.util.Map;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.AbstractCacheAbleService;
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.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.common.cache.SearchCacheMatchLogger;
import com.yoho.search.common.cache.model.SearchCache;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.model.SearchResult;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
@Service
public class FuzzySceneProductListService extends AbstractCacheAbleService {
private static final Logger logger = LoggerFactory.getLogger(ProductListSwitchService.class);
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private SearchSortHelper searchSortHelper;
@Autowired
private ProductListSortService productListSortService;
@Override
public SearchCache getSearchCache() {
return searchCacheFactory.getFuzzySearchCache();
}
/**
* 获取商品列表
*
* @param paramMap
* @return
* @throws Exception
*/
public SearchApiResult productList(Map<String, String> paramMap) {
try {
// 1)构造搜索参数
SearchParam searchParam = this.buildProductListSearchParam(paramMap);
// 2)从缓存中获取数据
final String indexName = ISearchConstants.INDEX_NAME_PRODUCT_INDEX;
JSONObject cacheObject = searchCacheService.getJSONObjectFromCache(this.searchCache, indexName, searchParam);
if (cacheObject != null) {
SearchCacheMatchLogger.doSearchCacheMatchLog("/scene/productList.json", paramMap);
return new SearchApiResult().setData(cacheObject);
}
// 3)查询ES
SearchResult searchResult = searchCommonService.doSearch(indexName, searchParam);
if (searchResult == null) {
return new SearchApiResult().setCode(500).setMessage("execption");
}
// 4)构造返回结果
JSONObject dataMap = new JSONObject();
dataMap.put("total", searchResult.getTotal());
dataMap.put("page", searchResult.getPage());
dataMap.put("page_size", searchParam.getSize());
dataMap.put("page_total", searchResult.getTotalPage());
List<Map<String, Object>> product_list = productIndexBaseService.getProductListWithPricePlan(searchResult.getResultList());
dataMap.put("product_list", productListSortService.sortProductList(product_list));// 处理一下商品的顺序;
// 5)将结果存进缓存
searchCacheService.addJSONObjectToCache(this.searchCache, indexName, searchParam, dataMap);
return new SearchApiResult().setData(dataMap);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return new SearchApiResult().setCode(500).setMessage("scene productList exception").setData(new JSONObject());
}
}
private SearchParam buildProductListSearchParam(Map<String, String> paramMap) throws Exception {
// 1)验证查询条数
int pageSize = StringUtils.isBlank(paramMap.get("viewNum")) ? 10 : Integer.parseInt(paramMap.get("viewNum"));
int page = StringUtils.isBlank(paramMap.get("page")) ? 1 : Integer.parseInt(paramMap.get("page"));
if (page < 1 || pageSize < 0) {
throw new IllegalArgumentException("分页参数不合法");
}
if (pageSize > 100) {
pageSize = 100;
}
// 2)构建基本查询参数
SearchParam searchParam = searchParamHelper.buildWithPersional(paramMap, true);
searchParam.setAggregationBuilders(null);
searchParam.setOffset((page - 1) * pageSize);
searchParam.setSize(pageSize);
// 3)设置排序字段
searchParam.setSortBuilders(searchSortHelper.buildSortList(paramMap));
// 4)设置返回的参数【节省带宽】
List<String> includeFields = productIndexBaseService.getProductIndexIncludeFields();
searchParam.setIncludeFields(includeFields);
return searchParam;
}
}
... ...
package com.yoho.search.service.scene.common;
import java.util.Map;
import com.yoho.search.recall.scene.NewSceneRecallService;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.recall.common.ProductListServiceHelper;
@Service
public class CommonSceneProductListService {
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private ProductListServiceHelper productListServiceHelper;
@Autowired
private NewSceneRecallService newSceneRecallService;
/**
* 各商品列表的入口
*
* @param paramMap
* @return
*/
public SearchApiResult productList(Map<String, String> paramMap) {
// 1、不是个性化,则直接走费个性化接口
if (!this.isPersionalScene(paramMap)) {
return productListServiceHelper.productListNotPersional(paramMap);
}
// 2、个性化时根据开关,决定是否使用高性能的场景
boolean searchPersionalNewStrategyOpen = searchDynamicConfigService.searchPersionalNewStrategyOpen();
if (searchPersionalNewStrategyOpen) {
return productListServiceHelper.productListForNewPersional(paramMap);
} else {
return productListServiceHelper.productListForDefaultPersional(paramMap);
}
}
private boolean isPersionalScene(Map<String, String> paramMap) {
if(!searchDynamicConfigService.openPersonalized()){
return false;
}
int uid = MapUtils.getIntValue(paramMap, "uid", 0);
String order = MapUtils.getString(paramMap, "order", "");
if (uid > 0 && StringUtils.isEmpty(order)) {
return true;
}
return false;
}
}
package com.yoho.search.service.list;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.recall.common.CommonRecallProductListService;
import com.yoho.search.recall.scene.SceneRecallProductListService;
import com.yoho.search.recall.sort.SortRecallProductListService;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.service.helper.SearchCommonHelper;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class ProductListSwitchService {
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private DefaultProductListService defaultProductListService;
@Autowired
private CommonRecallProductListService commonRecallProductListService;
@Autowired
private SceneRecallProductListService sceneRecallProductListService;
@Autowired
private SortRecallProductListService sortRecallProductListService;
@Autowired
private SearchCommonHelper searchCommonHelper;
/**
* 各商品列表的入口
*
* @param paramMap
* @return
*/
public SearchApiResult productList(Map<String, String> paramMap) {
// 1、不是个性化,则直接走费个性化接口
if (!this.isPersionalScene(paramMap)) {
return defaultProductListService.productListNotPersional(paramMap);
}
// 2、个性化时根据开关,决定是否使用高性能的场景-双11专用
boolean perfamanceStrategyOpen = searchDynamicConfigService.searchPersionalPerfamanceStrategyOpen();
if(perfamanceStrategyOpen){
return commonRecallProductListService.productList(paramMap);
}
// 3、品类页使用单独的召回页
boolean sortPageRecallOpen = searchDynamicConfigService.isSortPageRecallOpen();
if(sortPageRecallOpen && searchCommonHelper.isSortPageDefault(paramMap)){
return sortRecallProductListService.recallProductList(paramMap);
}
// 4、全部使用新的召回策略
boolean searchPersionalNewStrategyOpen = searchDynamicConfigService.searchPersionalNewStrategyOpen();
if (searchPersionalNewStrategyOpen) {
return sceneRecallProductListService.productList(paramMap);
}
// 4、使用向量版本的个性化方案
return defaultProductListService.productListForDefaultPersional(paramMap);
}
private boolean isPersionalScene(Map<String, String> paramMap) {
if(!searchDynamicConfigService.openPersonalized()){
return false;
}
int uid = MapUtils.getIntValue(paramMap, "uid", 0);
String order = MapUtils.getString(paramMap, "order", "");
if (uid > 0 && StringUtils.isEmpty(order)) {
return true;
}
return false;
}
}
... ...
package com.yoho.search.service.press;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.DateUtil;
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.models.SearchApiResult;
import com.yoho.search.service.base.SearchCommonService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@Service
public class PressTestService {
@Autowired
private SearchCommonService searchCommonService;
private SearchParam buildSearchParam(String brandIds, String smallSortIds, int size, String orderField, boolean withRange) {
SearchParam searchParam = new SearchParam();
// 设置filter
BoolQueryBuilder filter = QueryBuilders.boolQuery();
if (!StringUtils.isBlank(brandIds)) {
filter.must(QueryBuilders.termsQuery(ProductIndexEsField.brandId, brandIds.split(",")));
}
if (!StringUtils.isBlank(smallSortIds)) {
filter.must(QueryBuilders.termsQuery(ProductIndexEsField.smallSortId, smallSortIds.split(",")));
}
filter.must(QueryBuilders.termQuery(ProductIndexEsField.status, "1"));
if (withRange) {
filter.must(QueryBuilders.rangeQuery(ProductIndexEsField.firstShelveTime).lt(DateUtil.getTimeSecondByDate(DateUtil.addDay(new Date(), -(int) (90 * Math.random())))));
}
searchParam.setFiter(filter);
// 设置分页参数
searchParam.setOffset(0);
searchParam.setSize(size);
// 设置order
searchParam.setSortBuilders(this.sortBuilders(orderField));
// 设置返回字段
searchParam.setIncludeFields(Arrays.asList("productSkn", "productName"));
return searchParam;
}
private List<SortBuilder<?>> sortBuilders(String orderField) {
List<SortBuilder<?>> sortBuilders = new ArrayList<SortBuilder<?>>();
if (StringUtils.isNotBlank(orderField)) {
if ("random".equals(orderField)) {
sortBuilders.add(SortBuilders.scriptSort(new Script("Math.random()"), ScriptSortType.NUMBER).order(SortOrder.ASC));
} else {
sortBuilders.add(SortBuilders.fieldSort(orderField).order(SortOrder.DESC));
}
}
sortBuilders.add(SortBuilders.fieldSort(ProductIndexEsField.id).order(SortOrder.DESC));
return sortBuilders;
}
public SearchApiResult pressProductIndex(String brandIds, String smallSortIds, int size, String order, boolean withRange) {
// 设置order
SearchParam searchParam = this.buildSearchParam(brandIds, smallSortIds, size, order, withRange);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_INDEX, searchParam);
JSONObject result = new JSONObject();
result.put("product_list", searchResult.getResultList());
result.put("total", searchResult.getTotal());
return new SearchApiResult().setData(result);
}
public SearchApiResult pressProductBaseIndex(String brandIds, String smallSortIds, int size, String order, boolean withRange) {
// 设置order
SearchParam searchParam = this.buildSearchParam(brandIds, smallSortIds, size, order, withRange);
SearchResult searchResult = searchCommonService.doSearch(ISearchConstants.INDEX_NAME_PRODUCT_BASE_INDEX, searchParam);
JSONObject result = new JSONObject();
result.put("product_list", searchResult.getResultList());
result.put("total", searchResult.getTotal());
return new SearchApiResult().setData(result);
}
}
package com.yoho.search.service.scene;
import java.util.Map;
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 com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
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 java.util.Map;
@Service
public class BrandSceneService extends AbstractSceneService {
... ... @@ -22,7 +21,7 @@ public class BrandSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(BrandSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
package com.yoho.search.service.scene;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
import com.yoho.search.base.utils.ProductIndexEsField;
... ... @@ -40,11 +15,26 @@ import com.yoho.search.models.SortWithSizesVO;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.base.index.SizeIndexBaseService;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation;
import org.elasticsearch.search.aggregations.bucket.MultiBucketsAggregation.Bucket;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.tophits.TopHits;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;
@Service
public class BreakSizeSceneService extends AbstractSceneService {
... ... @@ -56,11 +46,9 @@ public class BreakSizeSceneService extends AbstractSceneService {
@Autowired
private SizeIndexBaseService sizeIndexBaseService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private SearchParamHelper searchParamHelper;
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
package com.yoho.search.service.scene;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class CommonSceneService extends AbstractSceneService {
... ... @@ -20,7 +19,7 @@ public class CommonSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(CouponSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
package com.yoho.search.service.scene;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class CouponSceneService extends AbstractSceneService {
... ... @@ -21,7 +20,7 @@ public class CouponSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(CouponSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -5,7 +5,7 @@ import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -22,7 +22,7 @@ public class FreeShippingOrderSceneService extends AbstractSceneService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Override
public void addParamsToParamMap(Map<String, String> paramMap) {
... ...
... ... @@ -5,6 +5,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.yoho.search.service.list.FuzzySceneProductListService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -21,10 +22,7 @@ import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.helper.SearchKeyWordHelper;
import com.yoho.search.service.scene.aggregations.SceneAggregationsHelper;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.FuzzySceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import com.yoho.search.service.service.IAggRecommendService;
import com.yoho.search.service.service.IProductIndexService;
import com.yoho.search.service.service.ISearchRecommendService;
@Service
... ...
... ... @@ -16,7 +16,7 @@ import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
... ... @@ -25,7 +25,7 @@ public class NewArrivalSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(NewArrivalSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -13,7 +13,7 @@ import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
... ... @@ -22,7 +22,7 @@ public class ProductPoolSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(ProductPoolSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -16,7 +16,7 @@ import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
... ... @@ -25,7 +25,7 @@ public class ReducePriceSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(ReducePriceSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -15,7 +15,7 @@ import com.yoho.search.core.es.agg.IAggregation;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
... ... @@ -24,7 +24,7 @@ public class ShopSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(ShopSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -3,14 +3,11 @@ package com.yoho.search.service.scene;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.SearchPageIdDefine;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.helper.SearchCommonHelper;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.aggregations.SceneAggregationsHelper;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
import com.yoho.search.recall.sort.SortRecallSceneService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -28,16 +25,10 @@ public class SortSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(SortSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
@Autowired
private SearchCommonHelper searchCommonHelper;
@Autowired
private SortRecallSceneService sortRecallSceneService;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private SceneAggregationsHelper sceneAggregationsHelper;
@Override
... ... @@ -83,21 +74,15 @@ public class SortSceneService extends AbstractSceneService {
}
// 1、添加默认参数
this.addParamsToParamMap(paramMap);
CompletableFuture<SearchApiResult> productListFuture = null;
// 2、获取商品列表-是否使用召回策略
if (goToRecall(paramMap)) {
productListFuture = CompletableFuture.supplyAsync(() -> sortRecallSceneService.recallProductList(this.newParamMap(paramMap)), executorService);
} else {
productListFuture = CompletableFuture.supplyAsync(() -> sceneProductListService.productList(this.newParamMap(paramMap)), executorService);
}
// 3、获取聚合结果
CompletableFuture<SearchApiResult> productListFuture = CompletableFuture.supplyAsync(() -> sceneProductListService.productList(this.newParamMap(paramMap)), executorService);
// 2、获取聚合结果
CompletableFuture<SearchApiResult> standardsFuture = CompletableFuture.supplyAsync(() -> sceneAggregationsHelper.sceneAggStandard(this.newParamMap(paramMap)),
executorService);
CompletableFuture<SearchApiResult> customizeTagFuture = CompletableFuture.supplyAsync(() -> sceneAggregationsHelper.sceneAggCustomizeTag(this.newParamMap(paramMap)),
executorService);
CompletableFuture<SearchApiResult> promotionsFuture = CompletableFuture.supplyAsync(() -> sceneAggregationsHelper.sceneAggPromotion(this.newParamMap(paramMap)),
executorService);
// 4、组合结果
// 3、组合结果
SearchApiResult productList = productListFuture.get();
SearchApiResult standards = standardsFuture.get();
SearchApiResult customizeTags = customizeTagFuture.get();
... ... @@ -113,20 +98,6 @@ public class SortSceneService extends AbstractSceneService {
}
}
private boolean goToRecall(Map<String, String> paramMap) {
if (!searchDynamicConfigService.isSortPageRecallOpen()) {
return false;
}
if (!searchCommonHelper.isOrderEmpty(paramMap)) {
return false;
}
int uid = searchCommonHelper.getUid(paramMap);
if (uid <= 0) {
return false;
}
return true;
}
@Override
public SearchApiResult aggregations(Map<String, String> paramMap) {
try {
... ...
... ... @@ -13,7 +13,7 @@ import com.yoho.search.common.utils.SearchApiResultUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.SearchRequestParams;
import com.yoho.search.service.scene.common.AbstractSceneService;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
import com.yoho.search.service.scene.common.SceneSelectionsService;
@Service
... ... @@ -22,7 +22,7 @@ public class ZqSceneService extends AbstractSceneService {
private static final Logger logger = LoggerFactory.getLogger(ZqSceneService.class);
@Autowired
private CommonSceneProductListService sceneProductListService;
private ProductListSwitchService sceneProductListService;
@Autowired
private SceneSelectionsService sceneSelectionsService;
... ...
... ... @@ -7,7 +7,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.list.ProductListSwitchService;
@Service
public class SearchProductsServiceNew {
... ... @@ -15,12 +15,12 @@ public class SearchProductsServiceNew {
@Autowired
private ISelectionsForPc selectionsForPc;
@Autowired
private CommonSceneProductListService commonSceneProductListService;
private ProductListSwitchService productListSwitchService;
@SuppressWarnings("unchecked")
public SearchApiResult searchProductsNew(Map<String, String> paramMap) {
Map<String, Object> result = new HashMap<String, Object>();
SearchApiResult productList = commonSceneProductListService.productList(paramMap);
SearchApiResult productList = productListSwitchService.productList(paramMap);
if (productList != null) {
result.putAll((Map<String, Object>) productList.getData());
}
... ...
package com.yoho.search.service.service.impl;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yoho.search.base.utils.ISearchConstants;
... ... @@ -25,12 +12,22 @@ import com.yoho.search.core.es.utils.SearchParamUtils;
import com.yoho.search.models.SearchApiResult;
import com.yoho.search.service.base.ProductListSortService;
import com.yoho.search.service.base.SearchCommonService;
import com.yoho.search.service.base.SearchDynamicConfigService;
import com.yoho.search.service.base.index.ProductIndexBaseService;
import com.yoho.search.service.helper.SearchParamHelper;
import com.yoho.search.service.helper.SearchSortHelper;
import com.yoho.search.service.scene.common.CommonSceneProductListService;
import com.yoho.search.service.service.IProductListService;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ProductListServiceImpl implements IProductListService {
... ... @@ -44,13 +41,9 @@ public class ProductListServiceImpl implements IProductListService {
@Autowired
private SearchCommonService searchCommonService;
@Autowired
private SearchDynamicConfigService searchDynamicConfigService;
@Autowired
private ProductIndexBaseService productIndexBaseService;
@Autowired
private ProductListSortService productListSortService;
@Autowired
private CommonSceneProductListService commonSceneProductListService;
@Override
... ...