Authored by hugufei

个性化因子对象重构

package com.yoho.search.recall.scene.beans.builder;
import com.yoho.search.base.utils.CollectionUtils;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import com.yoho.search.recall.scene.models.RecallParams;
import com.yoho.search.recall.scene.models.RecallMergerResult;
import com.yoho.search.recall.scene.models.RecallResult;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import com.yoho.search.recall.scene.beans.strategy.StrategyNameEnum;
import com.yoho.search.service.base.ProductListSortKey;
import com.yoho.search.service.base.ProductListSortService;
... ... @@ -22,7 +23,7 @@ public class RecallResultBuilder {
@Autowired
private ProductListSortService productListSortService;
public RecallResult builderRecallResult(RecallMergerResult recallMergerResult, RecallParams param, PersionalFactor persionalFactor){
public RecallResult builderRecallResult(RecallMergerResult recallMergerResult, RecallParams param, UserPersionalFactorRsp userPersionalFactorRsp){
//1、构造结果中的分页信息
final long total = recallMergerResult.getTotal();
... ... @@ -30,7 +31,7 @@ public class RecallResultBuilder {
List<RecallMergerResult.SknResult> sknResultList = recallMergerResult.getSknList();
//3、计算得分
this.doCalScore(sknResultList,persionalFactor);
this.doCalScore(sknResultList, userPersionalFactorRsp);
//4、排序
Collections.sort(sknResultList, new Comparator<RecallMergerResult.SknResult>() {
... ... @@ -71,8 +72,8 @@ public class RecallResultBuilder {
}
private void doCalScore(List<RecallMergerResult.SknResult> sknResultList, PersionalFactor persionalFactor) {
String userFactor = persionalFactor.getUserFactor();
private void doCalScore(List<RecallMergerResult.SknResult> sknResultList, UserPersionalFactorRsp userPersionalFactorRsp) {
String vector = userPersionalFactorRsp.getVector();
for (RecallMergerResult.SknResult sknResult : sknResultList) {
if (sknResult.getRequestTypes().contains(StrategyNameEnum.FIRST_PRODUCT_SKN.name())) {
sknResult.setScore(10000d);// firstSkn排第一个
... ...
package com.yoho.search.recall.scene.beans.builder;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.recall.scene.constants.SknCountConstants;
import com.yoho.search.recall.scene.models.ParamQueryFilter;
import com.yoho.search.recall.scene.models.RecallRequest;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import com.yoho.search.recall.scene.beans.strategy.impls.SortPriceStrategy;
import org.springframework.stereotype.Component;
... ... @@ -19,15 +20,15 @@ public class SortPriceRecallRequestBuilder{
* @param sortPriceAreas
* @return
*/
public List<RecallRequest> buildSortPriceRecallRequests(ParamQueryFilter paramQueryFilter, List<PersionalFactor.SortPriceArea> sortPriceAreas) {
public List<RecallRequest> buildSortPriceRecallRequests(ParamQueryFilter paramQueryFilter, List<SortPriceArea> sortPriceAreas) {
List<RecallRequest> requests = new ArrayList<>();
for (PersionalFactor.SortPriceArea sortPriceArea: sortPriceAreas) {
for (SortPriceArea sortPriceArea: sortPriceAreas) {
requests.add(this.buildSortPriceRecallRequest(paramQueryFilter,sortPriceArea, SknCountConstants.SORT_PRICE_TOATL));
}
return requests;
}
private RecallRequest buildSortPriceRecallRequest(ParamQueryFilter paramQueryFilter, PersionalFactor.SortPriceArea sortPriceArea, int size){
private RecallRequest buildSortPriceRecallRequest(ParamQueryFilter paramQueryFilter, SortPriceArea sortPriceArea, int size){
SortPriceStrategy strategy = new SortPriceStrategy(sortPriceArea,size);
return new RecallRequest(paramQueryFilter, strategy);
}
... ...
package com.yoho.search.recall.scene.beans.cache;
import com.yoho.search.recall.scene.beans.builder.BrandRecallRequestBuilder;
import com.yoho.search.recall.scene.beans.builder.CommonRecallRequestBuilder;
import com.yoho.search.recall.scene.beans.builder.SortPriceRecallRequestBuilder;
import com.yoho.search.recall.scene.beans.builder.RecallMergerResultBuilder;
import com.yoho.search.recall.scene.beans.builder.RecallResultBuilder;
import com.yoho.search.recall.scene.models.*;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import com.yoho.search.recall.scene.beans.builder.*;
import com.yoho.search.recall.scene.beans.persional.QueryUserPersionalFactorBean;
import com.yoho.search.recall.scene.models.CacheRecallRequestRecallResponse;
import com.yoho.search.recall.scene.models.CacheRecallParamsRecallResult;
import com.yoho.search.recall.scene.models.RecallRequest;
import com.yoho.search.recall.scene.models.RecallParams;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.recall.scene.models.RecallMergerResult;
import com.yoho.search.recall.scene.models.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
... ... @@ -77,35 +68,35 @@ public class QueryRecallResultCacheBean extends AbstractCacheBean<RecallParams,R
*/
private RecallResult doRealRecall(RecallParams param) {
//1、获取个性化因子
PersionalFactor persionalFactor = queryUserPersionalFactorBean.queryPersionalFactor(param);
UserPersionalFactorRsp userPersionalFactorRsp = queryUserPersionalFactorBean.queryPersionalFactor(param);
//2、构造请求
List<RecallRequest> batchRequests = this.buildBatchRequests(param, persionalFactor);
List<RecallRequest> batchRequests = this.buildBatchRequests(param, userPersionalFactorRsp);
//3、批量召回
List<CacheRecallRequestRecallResponse> requestResponses = batchRecallCacheBean.batchRecallAndCache(batchRequests);
//4、获取skn列表[去重]
RecallMergerResult recallMergerResult = recallMergerResultBuilder.buildRecallResponseBatch(requestResponses);
//5、构造真实结果[排序,截取skn]
RecallResult recallResult = recallResultBuilder.builderRecallResult(recallMergerResult, param, persionalFactor);
RecallResult recallResult = recallResultBuilder.builderRecallResult(recallMergerResult, param, userPersionalFactorRsp);
return recallResult;
}
/**
* 批量构造请求
* @param param
* @param persionalFactor
* @param userPersionalFactorRsp
* @return
*/
private List<RecallRequest> buildBatchRequests(RecallParams param, PersionalFactor persionalFactor) {
private List<RecallRequest> buildBatchRequests(RecallParams param, UserPersionalFactorRsp userPersionalFactorRsp) {
//1、构造召回请求
List<RecallRequest> allRequests = new ArrayList<>();
//2、构造非个性化的请求
List<RecallRequest> commonRequests = commonRequestBuilder.buildCommonRecallRequests(param.getParamQueryFilter(), param.getFirstProductSkns());
allRequests.addAll(commonRequests);
//4、构建个性化品牌的召回请求
List<RecallRequest> brandRequests = brandRequestBuilder.buildBrandRecallRequests(param.getParamQueryFilter(), persionalFactor.getBrandIds());
List<RecallRequest> brandRequests = brandRequestBuilder.buildBrandRecallRequests(param.getParamQueryFilter(), userPersionalFactorRsp.getBrandIds());
allRequests.addAll(brandRequests);
//5、构建个性化品牌的召回请求
List<RecallRequest> sortPriceRequests = sortPriceRequestBuilder.buildSortPriceRecallRequests(param.getParamQueryFilter(), persionalFactor.getSortPriceAreas());
List<RecallRequest> sortPriceRequests = sortPriceRequestBuilder.buildSortPriceRecallRequests(param.getParamQueryFilter(), userPersionalFactorRsp.getSortPriceAreas());
allRequests.addAll(sortPriceRequests);
return allRequests;
}
... ...
... ... @@ -2,7 +2,8 @@ package com.yoho.search.recall.scene.beans.helper;
import com.yoho.search.base.utils.DateUtil;
import com.yoho.search.base.utils.ProductIndexEsField;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
... ... @@ -124,7 +125,7 @@ public class ExtendFilterHelper {
* 品类价格带过滤器
* @return
*/
public static QueryBuilder sortPriceFilter (PersionalFactor.SortPriceArea sortPriceArea){
public static QueryBuilder sortPriceFilter (SortPriceArea sortPriceArea){
BoolQueryBuilder filter = QueryBuilders.boolQuery();
//must
filter.must(QueryBuilders.termQuery(ProductIndexEsField.middleSortId, sortPriceArea.getMiddleSortId()));
... ...
... ... @@ -6,8 +6,10 @@ import com.yoho.search.common.cache.SearchCacheFactory;
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.core.personalized.models.SortPriceArea;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import com.yoho.search.recall.scene.models.ParamQueryFilter;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import com.yoho.search.service.base.SearchCacheService;
import com.yoho.search.service.base.SearchCommonService;
import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
... ... @@ -47,7 +49,7 @@ class PagePersionalFactorComponent {
* @param paramQueryFilter
* @return
*/
public PersionalFactor queryPagePersionalFactor(ParamQueryFilter paramQueryFilter) {
public PagePersionalFactor queryPagePersionalFactor(ParamQueryFilter paramQueryFilter) {
//0、构造参数
SearchParam searchParam = new SearchParam();
searchParam.setQuery(paramQueryFilter.getParamQuery());
... ... @@ -67,9 +69,9 @@ class PagePersionalFactorComponent {
//3、缓存中获取
String cacheKey = searchCacheService.genSearchParamString(ISearchConstants.INDEX_NAME_PRODUCT_INDEX,searchParam);
PersionalFactor pagePersionalFactor = searchCacheService.getSerializableObjectFromCache(searchCache,cacheKey,PersionalFactor.class,true);
if(pagePersionalFactor!=null) {
return pagePersionalFactor;
PagePersionalFactor pagePagePersionalFactor = searchCacheService.getSerializableObjectFromCache(searchCache,cacheKey,PagePersionalFactor.class,true);
if(pagePagePersionalFactor !=null) {
return pagePagePersionalFactor;
}
//4、执行查询
... ... @@ -78,11 +80,11 @@ class PagePersionalFactorComponent {
//5、构造结果
Map<String, Aggregation> aggregationMap = searchResult.getAggMaps();
List<Integer> brandIds = this.getBrandIdsFromAggregationMap(aggregationMap);
List<PersionalFactor.SortPriceArea> sortPriceAreas = this.getSortPriceAreasFromAggregationMap(aggregationMap);
pagePersionalFactor = new PersionalFactor(brandIds, sortPriceAreas,null);
List<SortPriceArea> sortPriceAreas = this.getSortPriceAreasFromAggregationMap(aggregationMap);
pagePagePersionalFactor = new PagePersionalFactor(brandIds, sortPriceAreas);
//6、加入缓存
searchCacheService.addSerializableObjectToCache(searchCache,cacheKey,pagePersionalFactor,true);
return pagePersionalFactor;
searchCacheService.addSerializableObjectToCache(searchCache,cacheKey, pagePagePersionalFactor,true);
return pagePagePersionalFactor;
}
private List<Integer> getBrandIdsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
... ... @@ -100,8 +102,8 @@ class PagePersionalFactorComponent {
return brandIds;
}
private List<PersionalFactor.SortPriceArea> getSortPriceAreasFromAggregationMap(Map<String, Aggregation> aggregationMap) {
List<PersionalFactor.SortPriceArea> sortPrices = new ArrayList<>();
private List<SortPriceArea> getSortPriceAreasFromAggregationMap(Map<String, Aggregation> aggregationMap) {
List<SortPriceArea> sortPrices = new ArrayList<>();
MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggregationMap.get("middleSortIdAgg");
if (aggregation == null) {
return new ArrayList<>();
... ... @@ -119,7 +121,7 @@ class PagePersionalFactorComponent {
while (priceAreaIterator.hasNext()) {
MultiBucketsAggregation.Bucket genderBucket = priceAreaIterator.next();
Integer priceArea = Integer.valueOf(genderBucket.getKeyAsString());
sortPrices.add(new PersionalFactor.SortPriceArea(middleSortId, priceArea));
sortPrices.add(new SortPriceArea(middleSortId, priceArea));
}
}
return sortPrices;
... ...
package com.yoho.search.recall.scene.beans.persional;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import com.yoho.search.recall.scene.models.RecallParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -26,19 +28,19 @@ public class QueryUserPersionalFactorBean {
* @param recallParams
* @return
*/
public PersionalFactor queryPersionalFactor(RecallParams recallParams) {
public UserPersionalFactorRsp queryPersionalFactor(RecallParams recallParams) {
try {
//1、获取页面上的个性化因子
PersionalFactor pageFactor = pageComponent.queryPagePersionalFactor(recallParams.getParamQueryFilter());
PagePersionalFactor pageFactor = pageComponent.queryPagePersionalFactor(recallParams.getParamQueryFilter());
//2、获取用户的个性化因子
PersionalFactor userFactor = userComponent.queryUserPersionalFactor(recallParams.getUid(), recallParams.getUdid());
UserPersionalFactorRsp userFactor = userComponent.queryUserPersionalFactor(recallParams.getUid(), recallParams.getUdid());
//3、join获取最终的结果
List<Integer> brandIds = this.innerJoin(pageFactor.getBrandIds(),userFactor.getBrandIds(),10);
List<PersionalFactor.SortPriceArea> sortPriceAreas = this.innerJoin(pageFactor.getSortPriceAreas(),userFactor.getSortPriceAreas(),5);
return new PersionalFactor(brandIds, sortPriceAreas,userFactor.getUserFactor());
List<SortPriceArea> sortPriceAreas = this.innerJoin(pageFactor.getSortPriceAreas(),userFactor.getSortPriceAreas(),5);
return new UserPersionalFactorRsp(brandIds, sortPriceAreas,userFactor.getVector());
}catch (Exception e){
logger.error(e.getMessage());
return new PersionalFactor(new ArrayList<>(),new ArrayList<>(),"");
return new UserPersionalFactorRsp(new ArrayList<>(),new ArrayList<>(),"");
}
}
... ...
package com.yoho.search.recall.scene.beans.persional;
import com.yoho.core.rest.client.ServiceCaller;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.core.personalized.models.UserPersionalFactorReq;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import com.yoho.search.recall.scene.models.PersionalFactor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
... ... @@ -13,6 +15,8 @@ import java.util.List;
@Component
class UserPersionalFactorComponent {
private static final Logger logger = LoggerFactory.getLogger(UserPersionalFactorComponent.class);
@Autowired
private ServiceCaller serviceCaller;
... ... @@ -28,21 +32,32 @@ class UserPersionalFactorComponent {
* @param udid
* @return
*/
public PersionalFactor queryUserPersionalFactor(int uid, String udid) {
public UserPersionalFactorRsp queryUserPersionalFactor(int uid, String udid) {
//1、调大数据服务查询用户个性化因子
UserPersionalFactorRsp userPersionalFactorRsp = this.queryUserPersionalFactorRsp(uid,udid);
if(userPersionalFactorRsp!=null){
return userPersionalFactorRsp;
}
//2、查询失败则随机生成-测试用
List<Integer> brandIds = new ArrayList<Integer>();
for (int i = 0; i < 100; i++) {
brandIds.add((int) (Math.random() * 3000));
}
List<PersionalFactor.SortPriceArea> sortPriceArea = new ArrayList<PersionalFactor.SortPriceArea>();
List<SortPriceArea> sortPriceArea = new ArrayList<SortPriceArea>();
for (int i = 0; i < 50; i++) {
sortPriceArea.add(new PersionalFactor.SortPriceArea((int) (Math.random() * 1000), (int) (Math.random() *10)));
sortPriceArea.add(new SortPriceArea((int) (Math.random() * 1000), (int) (Math.random() *10)));
}
String factor = "";
return new PersionalFactor(brandIds, sortPriceArea,factor);
return new UserPersionalFactorRsp(brandIds, sortPriceArea,factor);
}
private UserPersionalFactorRsp queryUserPersionalFactorRsp( UserPersionalFactorReq userPersionalFactorReq){
return serviceCaller.call(SERVICE_NAME,userPersionalFactorReq,UserPersionalFactorRsp.class,timeOut);
private UserPersionalFactorRsp queryUserPersionalFactorRsp(int uid, String udid){
try {
UserPersionalFactorReq userPersionalFactorReq = new UserPersionalFactorReq(uid,udid);
return serviceCaller.call(SERVICE_NAME,userPersionalFactorReq,UserPersionalFactorRsp.class,timeOut);
}catch (Exception e){
logger.error(e.getMessage(),e);
return null;
}
}
}
... ...
package com.yoho.search.recall.scene.beans.strategy.impls;
import com.alibaba.fastjson.JSON;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.recall.scene.constants.CacheTimeConstants;
import com.yoho.search.recall.scene.beans.helper.ExtendFilterHelper;
import com.yoho.search.recall.scene.beans.helper.SortBuilderHelper;
import com.yoho.search.recall.scene.models.PersionalFactor;
import com.yoho.search.recall.scene.models.PagePersionalFactor;
import com.yoho.search.recall.scene.beans.strategy.IStrategy;
import com.yoho.search.recall.scene.beans.strategy.StrategyNameEnum;
import org.elasticsearch.index.query.QueryBuilder;
... ... @@ -12,10 +13,10 @@ import org.elasticsearch.search.sort.SortBuilder;
public class SortPriceStrategy implements IStrategy {
private PersionalFactor.SortPriceArea sortPriceArea;
private SortPriceArea sortPriceArea;
private int size;
public SortPriceStrategy(PersionalFactor.SortPriceArea sortPriceArea, int size) {
public SortPriceStrategy(SortPriceArea sortPriceArea, int size) {
this.sortPriceArea = sortPriceArea;
this.size = size;
}
... ...
package com.yoho.search.recall.scene.models;
import java.io.Serializable;
import java.util.List;
/**
* 个性化因子参数
*/
public class PersionalFactor implements Serializable{
private static final long serialVersionUID = 89030356435559223L;
private List<Integer> brandIds;
private List<SortPriceArea> sortPriceAreas;
private String userFactor;
public PersionalFactor() {
}
public PersionalFactor(List<Integer> brandIds, List<SortPriceArea> sortPriceAreas,String userFactor){
this.brandIds = brandIds;
this.sortPriceAreas = sortPriceAreas;
this.userFactor = userFactor;
}
public void setBrandIds(List<Integer> brandIds) {
this.brandIds = brandIds;
}
public void setSortPriceAreas(List<SortPriceArea> sortPriceAreas) {
this.sortPriceAreas = sortPriceAreas;
}
public List<Integer> getBrandIds() {
return brandIds;
}
public List<SortPriceArea> getSortPriceAreas() {
return sortPriceAreas;
}
public String getUserFactor() {
return userFactor;
}
public void setUserFactor(String userFactor) {
this.userFactor = userFactor;
}
public static class SortPriceArea implements Serializable{
private static final long serialVersionUID = -7973209074997705083L;
private Integer middleSortId;
private Integer priceArea;
public SortPriceArea() {
}
public SortPriceArea(Integer middleSortId, Integer priceArea) {
this.middleSortId = middleSortId;
this.priceArea = priceArea;
}
public Integer getMiddleSortId() {
return middleSortId;
}
public void setMiddleSortId(Integer middleSortId) {
this.middleSortId = middleSortId;
}
public Integer getPriceArea() {
return priceArea;
}
public void setPriceArea(Integer priceArea) {
this.priceArea = priceArea;
}
@Override
public boolean equals(Object o) {
SortPriceArea area = (SortPriceArea)o;
return this.middleSortId.equals(area.getMiddleSortId()) && this.priceArea.equals(area.getPriceArea());
}
}
}
package com.yoho.search.recall.scene.models;
import com.yoho.search.core.personalized.models.SortPriceArea;
import com.yoho.search.core.personalized.models.UserPersionalFactorRsp;
import java.io.Serializable;
import java.util.List;
/**
* 个性化因子参数
*/
public class PagePersionalFactor implements Serializable{
private static final long serialVersionUID = 89030356435559223L;
private List<Integer> brandIds;
private List<SortPriceArea> sortPriceAreas;
public PagePersionalFactor() {
}
public PagePersionalFactor(List<Integer> brandIds, List<SortPriceArea> sortPriceAreas){
this.brandIds = brandIds;
this.sortPriceAreas = sortPriceAreas;
}
public void setBrandIds(List<Integer> brandIds) {
this.brandIds = brandIds;
}
public void setSortPriceAreas(List<SortPriceArea> sortPriceAreas) {
this.sortPriceAreas = sortPriceAreas;
}
public List<Integer> getBrandIds() {
return brandIds;
}
public List<SortPriceArea> getSortPriceAreas() {
return sortPriceAreas;
}
}
... ...