Authored by hugufei

使用新对象构造页面的聚合元素

@@ -18,9 +18,6 @@ import java.util.Map; @@ -18,9 +18,6 @@ import java.util.Map;
18 @Component 18 @Component
19 public class RecallMergerResultBuilder { 19 public class RecallMergerResultBuilder {
20 20
21 - @Autowired  
22 - private QueryProductVectorInfoCacheBean queryProductVectorInfoCacheBean;  
23 -  
24 /** 21 /**
25 * 召回结果构造器 22 * 召回结果构造器
26 * 23 *
@@ -32,9 +29,7 @@ public class RecallMergerResultBuilder { @@ -32,9 +29,7 @@ public class RecallMergerResultBuilder {
32 long total = this.getTotalCount(requestResponses); 29 long total = this.getTotalCount(requestResponses);
33 //2、skn去重 30 //2、skn去重
34 List<RecallMergerResult.SknResult> sknResults = this.distinctRecallSkn(requestResponses); 31 List<RecallMergerResult.SknResult> sknResults = this.distinctRecallSkn(requestResponses);
35 - //3、填充向量  
36 - this.fillProductFactors(sknResults);  
37 - //4、返回召回结果 32 + //3、返回召回结果
38 return new RecallMergerResult(total, sknResults); 33 return new RecallMergerResult(total, sknResults);
39 } 34 }
40 35
@@ -100,18 +95,4 @@ public class RecallMergerResultBuilder { @@ -100,18 +95,4 @@ public class RecallMergerResultBuilder {
100 return sknResults; 95 return sknResults;
101 } 96 }
102 97
103 - private void fillProductFactors(List<RecallMergerResult.SknResult> sknResults) {  
104 - //1、请求构造  
105 - List<Integer> skns = new ArrayList<>();  
106 - for (RecallMergerResult.SknResult sknResult : sknResults) {  
107 - skns.add(sknResult.getProductSkn());  
108 - }  
109 - //2、执行查询  
110 - Map<Integer, String> productFactors = queryProductVectorInfoCacheBean.querySknVectors(skns);  
111 - //3、填充向量  
112 - for (RecallMergerResult.SknResult sknResult : sknResults) {  
113 - sknResult.setFactor(MapUtils.getString(productFactors,sknResult.getProductSkn(),""));  
114 - }  
115 - }  
116 -  
117 } 98 }
1 package com.yoho.search.recall.scene.beans.builder; 1 package com.yoho.search.recall.scene.beans.builder;
2 2
3 import com.yoho.search.base.utils.CollectionUtils; 3 import com.yoho.search.base.utils.CollectionUtils;
  4 +import com.yoho.search.base.utils.Transfer;
4 import com.yoho.search.core.personalized.PersonalizedSearch; 5 import com.yoho.search.core.personalized.PersonalizedSearch;
  6 +import com.yoho.search.core.personalized.models.SortPriceArea;
5 import com.yoho.search.core.personalized.models.UserPersonalFactorRsp; 7 import com.yoho.search.core.personalized.models.UserPersonalFactorRsp;
6 import com.yoho.search.recall.performance.beans.ProductFeatureFactorHepler; 8 import com.yoho.search.recall.performance.beans.ProductFeatureFactorHepler;
7 import com.yoho.search.recall.performance.model.CommonRecallResult; 9 import com.yoho.search.recall.performance.model.CommonRecallResult;
8 import com.yoho.search.recall.performance.model.CommonRecallSkn; 10 import com.yoho.search.recall.performance.model.CommonRecallSkn;
9 import com.yoho.search.recall.performance.model.UserFeatureFactor; 11 import com.yoho.search.recall.performance.model.UserFeatureFactor;
  12 +import com.yoho.search.recall.scene.beans.cache.QueryProductVectorInfoCacheBean;
10 import com.yoho.search.recall.scene.beans.strategy.StrategyNameEnum; 13 import com.yoho.search.recall.scene.beans.strategy.StrategyNameEnum;
11 import com.yoho.search.recall.scene.models.RecallMergerResult; 14 import com.yoho.search.recall.scene.models.RecallMergerResult;
12 import com.yoho.search.recall.scene.models.RecallParams; 15 import com.yoho.search.recall.scene.models.RecallParams;
@@ -35,6 +38,8 @@ public class RecallResultBuilder { @@ -35,6 +38,8 @@ public class RecallResultBuilder {
35 private PersonalVectorFeatureSearch personalVectorFeatureSearch; 38 private PersonalVectorFeatureSearch personalVectorFeatureSearch;
36 @Autowired 39 @Autowired
37 private ProductFeatureFactorHepler productFeatureFactorHepler; 40 private ProductFeatureFactorHepler productFeatureFactorHepler;
  41 + @Autowired
  42 + private QueryProductVectorInfoCacheBean queryProductVectorInfoCacheBean;
38 43
39 public RecallResult builderRecallResult(RecallMergerResult recallMergerResult, RecallParams param, UserPersonalFactorRsp userPersonalFactorRsp){ 44 public RecallResult builderRecallResult(RecallMergerResult recallMergerResult, RecallParams param, UserPersonalFactorRsp userPersonalFactorRsp){
40 //1、获取总数 45 //1、获取总数
@@ -43,16 +48,19 @@ public class RecallResultBuilder { @@ -43,16 +48,19 @@ public class RecallResultBuilder {
43 //2、获取召回结果中的所有skn 48 //2、获取召回结果中的所有skn
44 List<RecallMergerResult.SknResult> sknResultList = recallMergerResult.getSknList(); 49 List<RecallMergerResult.SknResult> sknResultList = recallMergerResult.getSknList();
45 50
46 - //3、按相关性计算得分 51 + //3、填充skn向量
  52 + sknResultList = this.fillProductFactors(sknResultList);
  53 +
  54 + //4、按相关性计算得分
47 sknResultList = this.doCalScoreAndSort(sknResultList,param.getUid()); 55 sknResultList = this.doCalScoreAndSort(sknResultList,param.getUid());
48 56
49 - //4、品牌品类平衡 57 + //5、品牌品类平衡
50 sknResultList = this.doBalance(sknResultList); 58 sknResultList = this.doBalance(sknResultList);
51 59
52 - //5、处理firstSkn-直通车等信息 60 + //6、处理firstSkn-直通车等信息
53 sknResultList = this.doReRank(sknResultList); 61 sknResultList = this.doReRank(sknResultList);
54 62
55 - //6、截取整数页 63 + //7、分页处理
56 int pageSize = param.getPageSize(); 64 int pageSize = param.getPageSize();
57 int recallTotalPage = (sknResultList.size() / pageSize); 65 int recallTotalPage = (sknResultList.size() / pageSize);
58 if (recallTotalPage == 0) { 66 if (recallTotalPage == 0) {
@@ -63,7 +71,7 @@ public class RecallResultBuilder { @@ -63,7 +71,7 @@ public class RecallResultBuilder {
63 } 71 }
64 sknResultList = CollectionUtils.safeSubList(sknResultList,0,recallTotalPage * param.getPageSize()); 72 sknResultList = CollectionUtils.safeSubList(sknResultList,0,recallTotalPage * param.getPageSize());
65 73
66 - //7、构造返回结果 74 + //8、构造返回结果
67 List<RecallSknInfo> sknList = new ArrayList<>(); 75 List<RecallSknInfo> sknList = new ArrayList<>();
68 for (RecallMergerResult.SknResult sknResult:sknResultList){ 76 for (RecallMergerResult.SknResult sknResult:sknResultList){
69 sknList.add(new RecallSknInfo(sknResult.getProductSkn(),sknResult.getRequestType())); 77 sknList.add(new RecallSknInfo(sknResult.getProductSkn(),sknResult.getRequestType()));
@@ -73,6 +81,26 @@ public class RecallResultBuilder { @@ -73,6 +81,26 @@ public class RecallResultBuilder {
73 } 81 }
74 82
75 /** 83 /**
  84 + * 查询skn的向量
  85 + * @param sknResults
  86 + * @return
  87 + */
  88 + private List<RecallMergerResult.SknResult> fillProductFactors(List<RecallMergerResult.SknResult> sknResults) {
  89 + //1、请求构造
  90 + List<Integer> skns = new ArrayList<>();
  91 + for (RecallMergerResult.SknResult sknResult : sknResults) {
  92 + skns.add(sknResult.getProductSkn());
  93 + }
  94 + //2、执行查询
  95 + Map<Integer, String> productFactors = queryProductVectorInfoCacheBean.querySknVectors(skns);
  96 + //3、填充向量
  97 + for (RecallMergerResult.SknResult sknResult : sknResults) {
  98 + sknResult.setFactor(MapUtils.getString(productFactors,sknResult.getProductSkn(),""));
  99 + }
  100 + return sknResults;
  101 + }
  102 +
  103 + /**
76 * 粗排-按相关性计算得分,并按得分排序 104 * 粗排-按相关性计算得分,并按得分排序
77 * @param sknResultList 105 * @param sknResultList
78 * @param uid 106 * @param uid
@@ -88,13 +116,8 @@ public class RecallResultBuilder { @@ -88,13 +116,8 @@ public class RecallResultBuilder {
88 double score = productFeatureFactorHepler.calProductFeatureFactor(userFeatureFactor, sknResult.getFactor()); 116 double score = productFeatureFactorHepler.calProductFeatureFactor(userFeatureFactor, sknResult.getFactor());
89 sknResult.setScore(score); 117 sknResult.setScore(score);
90 } 118 }
91 - //3、按得分排序  
92 - Collections.sort(sknResultList, new Comparator<RecallMergerResult.SknResult>() {  
93 - @Override  
94 - public int compare(RecallMergerResult.SknResult o1, RecallMergerResult.SknResult o2) {  
95 - return o2.getScore().compareTo(o1.getScore());// 大的排前面  
96 - }  
97 - }); 119 + //3、按得分排序-得分高的在前面
  120 + Collections.sort(sknResultList,(o1,o2)-> o2.getScore().compareTo(o1.getScore()));
98 return sknResultList; 121 return sknResultList;
99 } 122 }
100 123
@@ -6,9 +6,12 @@ import com.yoho.search.common.cache.SearchCacheFactory; @@ -6,9 +6,12 @@ import com.yoho.search.common.cache.SearchCacheFactory;
6 import com.yoho.search.common.cache.model.SearchCache; 6 import com.yoho.search.common.cache.model.SearchCache;
7 import com.yoho.search.core.es.model.SearchParam; 7 import com.yoho.search.core.es.model.SearchParam;
8 import com.yoho.search.core.es.model.SearchResult; 8 import com.yoho.search.core.es.model.SearchResult;
  9 +import com.yoho.search.core.personalized.models.SortBrand;
9 import com.yoho.search.core.personalized.models.SortPriceArea; 10 import com.yoho.search.core.personalized.models.SortPriceArea;
10 import com.yoho.search.recall.scene.models.ParamQueryFilter; 11 import com.yoho.search.recall.scene.models.ParamQueryFilter;
11 -import com.yoho.search.recall.scene.models.PagePersonalFactor; 12 +import com.yoho.search.recall.scene.models.personal.PagePersonalFactor;
  13 +import com.yoho.search.recall.scene.models.personal.PageSortBrand;
  14 +import com.yoho.search.recall.scene.models.personal.PageSortPriceArea;
12 import com.yoho.search.service.base.SearchCacheService; 15 import com.yoho.search.service.base.SearchCacheService;
13 import com.yoho.search.service.base.SearchCommonService; 16 import com.yoho.search.service.base.SearchCommonService;
14 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder; 17 import org.elasticsearch.search.aggregations.AbstractAggregationBuilder;
@@ -20,10 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired; @@ -20,10 +23,7 @@ import org.springframework.beans.factory.annotation.Autowired;
20 import org.springframework.stereotype.Component; 23 import org.springframework.stereotype.Component;
21 24
22 import javax.annotation.PostConstruct; 25 import javax.annotation.PostConstruct;
23 -import java.util.ArrayList;  
24 -import java.util.Iterator;  
25 -import java.util.List;  
26 -import java.util.Map; 26 +import java.util.*;
27 27
28 @Component 28 @Component
29 class PagePersionalFactorComponent { 29 class PagePersionalFactorComponent {
@@ -49,21 +49,17 @@ class PagePersionalFactorComponent { @@ -49,21 +49,17 @@ class PagePersionalFactorComponent {
49 * @return 49 * @return
50 */ 50 */
51 public PagePersonalFactor queryPagePersionalFactor(ParamQueryFilter paramQueryFilter) { 51 public PagePersonalFactor queryPagePersionalFactor(ParamQueryFilter paramQueryFilter) {
52 - //0、构造参数 52 + //1、构造参数
53 SearchParam searchParam = new SearchParam(); 53 SearchParam searchParam = new SearchParam();
54 searchParam.setQuery(paramQueryFilter.getParamQuery()); 54 searchParam.setQuery(paramQueryFilter.getParamQuery());
55 searchParam.setFiter(paramQueryFilter.getParamFilter()); 55 searchParam.setFiter(paramQueryFilter.getParamFilter());
56 searchParam.setSize(0); 56 searchParam.setSize(0);
57 - List<AbstractAggregationBuilder<?>> aggregationBuilders = new ArrayList<>();  
58 -  
59 - //1、品牌id聚合  
60 - aggregationBuilders.add(AggregationBuilders.terms("brandIdAgg").field(ProductIndexEsField.brandId).size(200));//品牌id聚合  
61 57
62 - //2、品类价格带聚合  
63 - TermsAggregationBuilder middleAggBuilder = AggregationBuilders.terms("middleSortIdAgg").field(ProductIndexEsField.middleSortId).size(100);  
64 - TermsAggregationBuilder genderAggBuilder = AggregationBuilders.terms("priceAreaAgg").field(ProductIndexEsField.priceArea).size(7);  
65 - middleAggBuilder.subAggregation(genderAggBuilder);  
66 - aggregationBuilders.add(middleAggBuilder);//品类性格聚合 58 + //2、构造聚合参数
  59 + List<AbstractAggregationBuilder<?>> aggregationBuilders = new ArrayList<>();
  60 + aggregationBuilders.add(brandIdAggBuilder());//品牌id聚合
  61 + aggregationBuilders.add(sortPriceAreaAggBuilder());//品类-价格带聚合
  62 + aggregationBuilders.add(sortBrandAggBuilder());//品类-品牌聚合
67 searchParam.setAggregationBuilders(aggregationBuilders); 63 searchParam.setAggregationBuilders(aggregationBuilders);
68 64
69 //3、缓存中获取 65 //3、缓存中获取
@@ -79,15 +75,25 @@ class PagePersionalFactorComponent { @@ -79,15 +75,25 @@ class PagePersionalFactorComponent {
79 //5、构造结果 75 //5、构造结果
80 Map<String, Aggregation> aggregationMap = searchResult.getAggMaps(); 76 Map<String, Aggregation> aggregationMap = searchResult.getAggMaps();
81 List<Integer> brandIds = this.getBrandIdsFromAggregationMap(aggregationMap); 77 List<Integer> brandIds = this.getBrandIdsFromAggregationMap(aggregationMap);
82 - List<SortPriceArea> sortPriceAreas = this.getSortPriceAreasFromAggregationMap(aggregationMap);  
83 - pagePagePersonalFactor = new PagePersonalFactor(brandIds, sortPriceAreas); 78 + List<PageSortPriceArea> sortPriceAreas = this.getSortPriceAreasFromAggregationMap(aggregationMap);
  79 + List<PageSortBrand> sortBrands = this.getSortBrandsFromAggregationMap(aggregationMap);
  80 +
  81 + pagePagePersonalFactor = new PagePersonalFactor(brandIds, sortPriceAreas,sortBrands);
84 //6、加入缓存 82 //6、加入缓存
85 searchCacheService.addSerializableObjectToCache(searchCache,cacheKey, pagePagePersonalFactor,true); 83 searchCacheService.addSerializableObjectToCache(searchCache,cacheKey, pagePagePersonalFactor,true);
86 return pagePagePersonalFactor; 84 return pagePagePersonalFactor;
87 } 85 }
88 86
  87 + /**
  88 + * 品牌id聚合
  89 + * @return
  90 + */
  91 + private TermsAggregationBuilder brandIdAggBuilder() {
  92 + return AggregationBuilders.terms("brandIdAgg").field(ProductIndexEsField.brandId).size(200);
  93 + }
  94 +
89 private List<Integer> getBrandIdsFromAggregationMap(Map<String, Aggregation> aggregationMap) { 95 private List<Integer> getBrandIdsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
90 - List<Integer> brandIds = new ArrayList<Integer>(); 96 + List<Integer> brandIds = new ArrayList<>();
91 MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggregationMap.get("brandIdAgg"); 97 MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggregationMap.get("brandIdAgg");
92 if (aggregation == null) { 98 if (aggregation == null) {
93 return brandIds; 99 return brandIds;
@@ -101,29 +107,89 @@ class PagePersionalFactorComponent { @@ -101,29 +107,89 @@ class PagePersionalFactorComponent {
101 return brandIds; 107 return brandIds;
102 } 108 }
103 109
104 - private List<SortPriceArea> getSortPriceAreasFromAggregationMap(Map<String, Aggregation> aggregationMap) {  
105 - List<SortPriceArea> sortPrices = new ArrayList<>();  
106 - MultiBucketsAggregation aggregation = (MultiBucketsAggregation) aggregationMap.get("middleSortIdAgg");  
107 - if (aggregation == null) {  
108 - return new ArrayList<>(); 110 + /**
  111 + * 品类-价格带聚合
  112 + * @return
  113 + */
  114 + private TermsAggregationBuilder sortPriceAreaAggBuilder() {
  115 + TermsAggregationBuilder middleSortAggBuilder = AggregationBuilders.terms("sortPriceMiddleSortIdAgg").field(ProductIndexEsField.middleSortId).size(100);
  116 + TermsAggregationBuilder priceAreaAggBuilder = AggregationBuilders.terms("sortPricePriceAreaAgg").field(ProductIndexEsField.priceArea).size(10);
  117 + middleSortAggBuilder.subAggregation(priceAreaAggBuilder);
  118 + return middleSortAggBuilder;
  119 + }
  120 +
  121 + private List<PageSortPriceArea> getSortPriceAreasFromAggregationMap(Map<String, Aggregation> aggregationMap) {
  122 + Map<Integer,List<Integer>> sortPriceAreaMap = this.getValueFromAggregationMap(aggregationMap,"sortPriceMiddleSortIdAgg","sortPricePriceAreaAgg");
  123 + List<PageSortPriceArea> sortPrices = new ArrayList<>();
  124 + for (Map.Entry<Integer,List<Integer>> entry: sortPriceAreaMap.entrySet()) {
  125 + Integer middleSortId = entry.getKey();
  126 + List<Integer> priceAreas = entry.getValue();
  127 + sortPrices.add(new PageSortPriceArea(middleSortId,priceAreas));
  128 + }
  129 + return sortPrices;
109 } 130 }
110 - Iterator<? extends MultiBucketsAggregation.Bucket> iterator = aggregation.getBuckets().iterator();  
111 - while (iterator.hasNext()) {  
112 - MultiBucketsAggregation.Bucket middleSortIdBucket = iterator.next();  
113 - Integer middleSortId = Integer.valueOf(middleSortIdBucket.getKeyAsString());  
114 131
115 - MultiBucketsAggregation priceAreaAggregation = ((MultiBucketsAggregation) middleSortIdBucket.getAggregations().asMap().get("priceAreaAgg"));  
116 - if(priceAreaAggregation==null){ 132 + /**
  133 + * 品类-品牌聚合
  134 + *
  135 + * @return
  136 + */
  137 + private TermsAggregationBuilder sortBrandAggBuilder() {
  138 + TermsAggregationBuilder middleSortAggBuilder = AggregationBuilders.terms("sortBrandMiddleSortIdAgg").field(ProductIndexEsField.middleSortId).size(100);
  139 + middleSortAggBuilder.subAggregation(AggregationBuilders.terms("sortBrandBrandIdAgg").field(ProductIndexEsField.brandId).size(200));
  140 + return middleSortAggBuilder;
  141 + }
  142 +
  143 + private List<PageSortBrand> getSortBrandsFromAggregationMap(Map<String, Aggregation> aggregationMap) {
  144 + Map<Integer,List<Integer>> sortBrandMap = this.getValueFromAggregationMap(aggregationMap,"sortBrandMiddleSortIdAgg","sortBrandBrandIdAgg");
  145 + List<PageSortBrand> pageSortBrands = new ArrayList<>();
  146 + for (Map.Entry<Integer,List<Integer>> entry: sortBrandMap.entrySet()) {
  147 + Integer middleSortId = entry.getKey();
  148 + List<Integer> brandIds = entry.getValue();
  149 + pageSortBrands.add(new PageSortBrand(middleSortId,brandIds));
  150 + }
  151 + return pageSortBrands;
  152 + }
  153 +
  154 + /**
  155 + * 从聚合结果中获取参数,仅支持二层聚合
  156 + * @param aggregationMap
  157 + * @param firstAggName
  158 + * @param secondAggName
  159 + * @return
  160 + */
  161 + private Map<Integer,List<Integer>> getValueFromAggregationMap(Map<String, Aggregation> aggregationMap,String firstAggName,String secondAggName){
  162 + Map<Integer,List<Integer>> aggResultMap = new HashMap<>();
  163 + if(!aggregationMap.containsKey(firstAggName)){
  164 + return aggResultMap;
  165 + }
  166 + MultiBucketsAggregation firstAggregation = (MultiBucketsAggregation) aggregationMap.get(firstAggName);
  167 + Iterator<? extends MultiBucketsAggregation.Bucket> firstAggregationIterator = firstAggregation.getBuckets().iterator();
  168 + while (firstAggregationIterator.hasNext()) {
  169 + MultiBucketsAggregation.Bucket firstAggregationBucket = firstAggregationIterator.next();
  170 + Integer firstAggregationBucketKey = Integer.valueOf(firstAggregationBucket.getKeyAsString());
  171 + Map<String, Aggregation> secondAggregationMap = firstAggregationBucket.getAggregations().asMap();
  172 + if(secondAggregationMap==null || !secondAggregationMap.containsKey(secondAggName)){
117 continue; 173 continue;
118 } 174 }
119 - Iterator<? extends MultiBucketsAggregation.Bucket> priceAreaIterator = priceAreaAggregation.getBuckets().iterator();  
120 - while (priceAreaIterator.hasNext()) {  
121 - MultiBucketsAggregation.Bucket genderBucket = priceAreaIterator.next();  
122 - Integer priceArea = Integer.valueOf(genderBucket.getKeyAsString());  
123 - sortPrices.add(new SortPriceArea(middleSortId, priceArea)); 175 + List<Integer> secondAggregationBucketKeys = this.getAggValuesFromMultiBucketsAggregation((MultiBucketsAggregation)secondAggregationMap.get(secondAggName));
  176 + aggResultMap.put(firstAggregationBucketKey,secondAggregationBucketKeys);
124 } 177 }
  178 + return aggResultMap;
125 } 179 }
126 - return sortPrices; 180 +
  181 + private List<Integer> getAggValuesFromMultiBucketsAggregation(MultiBucketsAggregation aggregation){
  182 + List<Integer> results = new ArrayList<>();
  183 + if(aggregation==null){
  184 + return results;
  185 + }
  186 + Iterator<? extends MultiBucketsAggregation.Bucket> bucketsIterator = aggregation.getBuckets().iterator();
  187 + while (bucketsIterator.hasNext()) {
  188 + MultiBucketsAggregation.Bucket bucket = bucketsIterator.next();
  189 + Integer value = Integer.valueOf(bucket.getKeyAsString());
  190 + results.add(value);
  191 + }
  192 + return results;
127 } 193 }
128 194
129 } 195 }
@@ -5,16 +5,16 @@ import com.yoho.search.base.utils.CollectionUtils; @@ -5,16 +5,16 @@ import com.yoho.search.base.utils.CollectionUtils;
5 import com.yoho.search.base.utils.Transfer; 5 import com.yoho.search.base.utils.Transfer;
6 import com.yoho.search.core.personalized.models.SortPriceArea; 6 import com.yoho.search.core.personalized.models.SortPriceArea;
7 import com.yoho.search.core.personalized.models.UserPersonalFactorRsp; 7 import com.yoho.search.core.personalized.models.UserPersonalFactorRsp;
8 -import com.yoho.search.recall.scene.models.PagePersonalFactor; 8 +import com.yoho.search.recall.scene.constants.RecallCommonConstants;
  9 +import com.yoho.search.recall.scene.models.personal.PagePersonalFactor;
9 import com.yoho.search.recall.scene.models.RecallParams; 10 import com.yoho.search.recall.scene.models.RecallParams;
  11 +import com.yoho.search.recall.scene.models.personal.PageSortPriceArea;
10 import org.slf4j.Logger; 12 import org.slf4j.Logger;
11 import org.slf4j.LoggerFactory; 13 import org.slf4j.LoggerFactory;
12 import org.springframework.beans.factory.annotation.Autowired; 14 import org.springframework.beans.factory.annotation.Autowired;
13 import org.springframework.stereotype.Component; 15 import org.springframework.stereotype.Component;
14 16
15 -import java.util.ArrayList;  
16 -import java.util.List;  
17 -import java.util.Map; 17 +import java.util.*;
18 18
19 @Component 19 @Component
20 public class QueryUserPersionalFactorBean { 20 public class QueryUserPersionalFactorBean {
@@ -39,60 +39,73 @@ public class QueryUserPersionalFactorBean { @@ -39,60 +39,73 @@ public class QueryUserPersionalFactorBean {
39 //1、获取页面上的个性化因子 39 //1、获取页面上的个性化因子
40 long begin = System.currentTimeMillis(); 40 long begin = System.currentTimeMillis();
41 PagePersonalFactor pageFactor = pageComponent.queryPagePersionalFactor(recallParams.getParamQueryFilter()); 41 PagePersonalFactor pageFactor = pageComponent.queryPagePersionalFactor(recallParams.getParamQueryFilter());
42 - RECALL_NEW_LOGGER.info("queryPagePersionalFactor . cost is[{}]",System.currentTimeMillis()-begin); 42 + RECALL_NEW_LOGGER.info("queryPagePersionalFactor . cost is[{}]", System.currentTimeMillis() - begin);
43 //2、获取用户的个性化因子 43 //2、获取用户的个性化因子
44 begin = System.currentTimeMillis(); 44 begin = System.currentTimeMillis();
45 UserPersonalFactorRsp userFactor = userComponent.queryUserPersionalFactor(recallParams.getUid(), recallParams.getUdid()); 45 UserPersonalFactorRsp userFactor = userComponent.queryUserPersionalFactor(recallParams.getUid(), recallParams.getUdid());
46 - RECALL_NEW_LOGGER.info("queryUserPersionalFactor . cost is[{}]",System.currentTimeMillis()-begin); 46 + RECALL_NEW_LOGGER.info("queryUserPersionalFactor . cost is[{}]", System.currentTimeMillis() - begin);
47 //3、join获取最终的结果 47 //3、join获取最终的结果
48 begin = System.currentTimeMillis(); 48 begin = System.currentTimeMillis();
49 - List<Integer> brandIds = this.innerJoin(pageFactor.getBrandIds(),userFactor.getBrandIds(),brandIdMapkeyTransfer,15);  
50 - List<SortPriceArea> sortPriceAreas = this.innerJoin(pageFactor.getSortPriceAreas(),userFactor.getSortPriceAreas(),sortPriceMapkeyTransfer,10);  
51 - UserPersonalFactorRsp userPersonalFactorRsp = new UserPersonalFactorRsp(brandIds, sortPriceAreas,userFactor.getVector());  
52 - RECALL_NEW_LOGGER.info("innerJoinFactor . cost is[{}],uid is[{}], data is [{}] ", System.currentTimeMillis()-begin,recallParams.getUid(), JSON.toJSONString(userPersonalFactorRsp)); 49 + List<Integer> brandIds = this.getBrandListWithSort(pageFactor, userFactor);
  50 + List<SortPriceArea> sortPriceAreas = this.getSortPriceAreaWithSort(pageFactor, userFactor);
  51 + //4、构造UserPersonalFactorRsp
  52 + UserPersonalFactorRsp userPersonalFactorRsp = new UserPersonalFactorRsp(brandIds, sortPriceAreas, userFactor.getVector());
  53 + RECALL_NEW_LOGGER.info("innerJoinFactor . cost is[{}],uid is[{}], data is [{}] ", System.currentTimeMillis() - begin, recallParams.getUid(), JSON.toJSONString(userPersonalFactorRsp));
53 return userPersonalFactorRsp; 54 return userPersonalFactorRsp;
54 - }catch (Exception e){  
55 - logger.error(e.getMessage(),e);  
56 - return new UserPersonalFactorRsp(new ArrayList<>(),new ArrayList<>(),""); 55 + } catch (Exception e) {
  56 + logger.error(e.getMessage(), e);
  57 + return new UserPersonalFactorRsp(new ArrayList<>(), new ArrayList<>(), "");
57 } 58 }
58 } 59 }
59 60
60 - static Transfer<Integer,String> brandIdMapkeyTransfer = new Transfer<Integer, String>() {  
61 - @Override  
62 - public String transfer(Integer brandId) {  
63 - return String.valueOf(brandId); 61 + /**
  62 + * 按顺序截取品牌
  63 + * @param pageFactor
  64 + * @param userFactor
  65 + * @return
  66 + */
  67 + private List<Integer> getBrandListWithSort(PagePersonalFactor pageFactor, UserPersonalFactorRsp userFactor){
  68 + List<Integer> pageBrandIds = pageFactor.getBrandIds();
  69 + List<Integer> userBrandIds = userFactor.getBrandIds();
  70 + List<Integer> results = new ArrayList<>();
  71 + for (Integer brandId : userBrandIds) {
  72 + if (pageBrandIds.contains(brandId)) {
  73 + results.add(brandId);
64 } 74 }
65 - };  
66 -  
67 - static Transfer<SortPriceArea,String> sortPriceMapkeyTransfer = new Transfer<SortPriceArea, String>() {  
68 - @Override  
69 - public String transfer(SortPriceArea sortPriceArea) {  
70 - StringBuilder sb = new StringBuilder();  
71 - sb.append(sortPriceArea.getMiddleSortId());  
72 - sb.append(":");  
73 - sb.append(sortPriceArea.getPriceArea());  
74 - return sb.toString(); 75 + if (results.size() >= RecallCommonConstants.MAX_JOIN_BRANDID){
  76 + break;
  77 + }
  78 + }
  79 + return results;
75 } 80 }
76 - };  
77 81
78 - private <T> List<T> innerJoin(List<T> aList, List<T> bList, Transfer<T,String> mapKeyTransfer,int size) {  
79 - try {  
80 - Map<String,T> aKeyValueMap = CollectionUtils.toMap(aList,mapKeyTransfer);  
81 - List<T> results = new ArrayList<T>();  
82 - for (T b : bList) {  
83 - String bKey = mapKeyTransfer.transfer(b);  
84 - if (aKeyValueMap.containsKey(bKey)) {  
85 - results.add(aKeyValueMap.get(bKey)); 82 + /**
  83 + * 按顺序截取品类-价格带
  84 + * @param pageFactor
  85 + * @param userFactor
  86 + * @return
  87 + */
  88 + private List<SortPriceArea> getSortPriceAreaWithSort(PagePersonalFactor pageFactor, UserPersonalFactorRsp userFactor){
  89 + List<PageSortPriceArea> pageSortPriceAreas = pageFactor.getSortPriceAreas();
  90 + Map<Integer,List<Integer>> sortPriceAreaMap = new HashMap<>();
  91 + for (PageSortPriceArea pageSortPriceArea: pageSortPriceAreas) {
  92 + sortPriceAreaMap.put(pageSortPriceArea.getMiddleSortId(),pageSortPriceArea.getPriceAreas());
86 } 93 }
87 - if (results.size() >= size) { 94 + List<SortPriceArea> results = new ArrayList<>();
  95 + for (SortPriceArea sortPriceArea : userFactor.getSortPriceAreas()) {
  96 + if(!sortPriceAreaMap.containsKey(sortPriceArea.getMiddleSortId())){
  97 + continue;
  98 + }
  99 + List<Integer> priceArea = sortPriceAreaMap.get(sortPriceArea.getMiddleSortId());
  100 + if(priceArea==null || !priceArea.contains(sortPriceArea.getPriceArea())){
  101 + continue;
  102 + }
  103 + results.add(sortPriceArea);
  104 + if (results.size() >= RecallCommonConstants.MAX_JOIN_SORT_BRAND){
88 break; 105 break;
89 } 106 }
90 } 107 }
91 return results; 108 return results;
92 - }catch (Exception e){  
93 - logger.error(e.getMessage(),e);  
94 - return new ArrayList<>();  
95 - }  
96 } 109 }
97 110
98 } 111 }
  1 +package com.yoho.search.recall.scene.constants;
  2 +
  3 +public class RecallCommonConstants {
  4 +
  5 + public static final int MAX_JOIN_BRANDID = 20;
  6 +
  7 + public static final int MAX_JOIN_SORT_PRICE = 10;
  8 +
  9 + public static final int MAX_JOIN_SORT_BRAND= 50;
  10 +
  11 +}
@@ -28,6 +28,7 @@ public class RecallMergerResult { @@ -28,6 +28,7 @@ public class RecallMergerResult {
28 private Integer productSkn; 28 private Integer productSkn;
29 private Integer brandId; 29 private Integer brandId;
30 private Integer middleSortId; 30 private Integer middleSortId;
  31 + private Integer priceArea;
31 private String requestType; 32 private String requestType;
32 private String factor; 33 private String factor;
33 private Double score; 34 private Double score;
@@ -36,6 +37,7 @@ public class RecallMergerResult { @@ -36,6 +37,7 @@ public class RecallMergerResult {
36 this.productSkn = recallSkn.getSkn(); 37 this.productSkn = recallSkn.getSkn();
37 this.brandId = recallSkn.getBdId(); 38 this.brandId = recallSkn.getBdId();
38 this.middleSortId = recallSkn.getMisId(); 39 this.middleSortId = recallSkn.getMisId();
  40 + this.priceArea = recallSkn.getPa();
39 } 41 }
40 42
41 public Integer getProductSkn() { 43 public Integer getProductSkn() {
@@ -50,29 +52,35 @@ public class RecallMergerResult { @@ -50,29 +52,35 @@ public class RecallMergerResult {
50 return middleSortId; 52 return middleSortId;
51 } 53 }
52 54
53 - public String getRequestType() {  
54 - return requestType; 55 + public Integer getPriceArea() {
  56 + return priceArea;
55 } 57 }
56 58
57 public void setRequestType(String requestType) { 59 public void setRequestType(String requestType) {
58 this.requestType = requestType; 60 this.requestType = requestType;
59 } 61 }
60 62
61 - public Double getScore() {  
62 - return score; 63 +
  64 + public String getRequestType() {
  65 + return requestType;
63 } 66 }
64 67
65 public void setScore(Double score) { 68 public void setScore(Double score) {
66 this.score = score; 69 this.score = score;
67 } 70 }
68 71
69 - public String getFactor() {  
70 - return factor; 72 + public Double getScore() {
  73 + return score;
71 } 74 }
72 75
73 public void setFactor(String factor) { 76 public void setFactor(String factor) {
74 this.factor = factor; 77 this.factor = factor;
75 } 78 }
  79 +
  80 + public String getFactor() {
  81 + return factor;
  82 + }
  83 +
76 } 84 }
77 85
78 } 86 }
@@ -46,14 +46,16 @@ public class RecallResponse implements Serializable { @@ -46,14 +46,16 @@ public class RecallResponse implements Serializable {
46 private Integer skn; 46 private Integer skn;
47 private Integer bdId; 47 private Integer bdId;
48 private Integer misId; 48 private Integer misId;
  49 + private Integer pa;
49 50
50 public RecallSkn() { 51 public RecallSkn() {
51 } 52 }
52 53
53 - public RecallSkn(Integer productSkn, Integer brandId, Integer middleSortId) { 54 + public RecallSkn(Integer productSkn, Integer brandId, Integer middleSortId,Integer pa) {
54 this.skn = productSkn; 55 this.skn = productSkn;
55 this.bdId = brandId; 56 this.bdId = brandId;
56 this.misId = middleSortId; 57 this.misId = middleSortId;
  58 + this.pa = pa;
57 } 59 }
58 60
59 public Integer getSkn() { 61 public Integer getSkn() {
@@ -79,6 +81,14 @@ public class RecallResponse implements Serializable { @@ -79,6 +81,14 @@ public class RecallResponse implements Serializable {
79 public void setMisId(Integer misId) { 81 public void setMisId(Integer misId) {
80 this.misId = misId; 82 this.misId = misId;
81 } 83 }
  84 +
  85 + public Integer getPa() {
  86 + return pa;
  87 + }
  88 +
  89 + public void setPa(Integer pa) {
  90 + this.pa = pa;
  91 + }
82 } 92 }
83 93
84 } 94 }
  1 +package com.yoho.search.recall.scene.models.personal;
  2 +
  3 +import com.yoho.search.core.personalized.models.SortBrand;
  4 +import com.yoho.search.core.personalized.models.SortPriceArea;
  5 +
  6 +import java.io.Serializable;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 个性化因子参数
  11 + */
  12 +public class PagePersonalFactor implements Serializable{
  13 +
  14 + private static final long serialVersionUID = 89030356435559223L;
  15 +
  16 + private List<Integer> brandIds;
  17 + private List<PageSortPriceArea> sortPriceAreas;
  18 + private List<PageSortBrand> sortBrands;
  19 +
  20 + public PagePersonalFactor() {
  21 + }
  22 +
  23 + public PagePersonalFactor(List<Integer> brandIds, List<PageSortPriceArea> sortPriceAreas,List<PageSortBrand> sortBrands){
  24 + this.brandIds = brandIds;
  25 + this.sortPriceAreas = sortPriceAreas;
  26 + this.sortBrands = sortBrands;
  27 + }
  28 +
  29 + public List<Integer> getBrandIds() {
  30 + return brandIds;
  31 + }
  32 +
  33 + public void setBrandIds(List<Integer> brandIds) {
  34 + this.brandIds = brandIds;
  35 + }
  36 +
  37 + public List<PageSortPriceArea> getSortPriceAreas() {
  38 + return sortPriceAreas;
  39 + }
  40 +
  41 + public void setSortPriceAreas(List<PageSortPriceArea> sortPriceAreas) {
  42 + this.sortPriceAreas = sortPriceAreas;
  43 + }
  44 +
  45 + public List<PageSortBrand> getSortBrands() {
  46 + return sortBrands;
  47 + }
  48 +
  49 + public void setSortBrands(List<PageSortBrand> sortBrands) {
  50 + this.sortBrands = sortBrands;
  51 + }
  52 +}
  1 +package com.yoho.search.recall.scene.models.personal;
  2 +
  3 +import java.io.Serializable;
  4 +import java.util.List;
  5 +
  6 +public class PageSortBrand implements Serializable {
  7 + private static final long serialVersionUID = 6155493513881738094L;
  8 + private Integer middleSortId;
  9 + private List<Integer> brandIds;
  10 +
  11 + public PageSortBrand() {
  12 + }
  13 +
  14 + public PageSortBrand(Integer middleSortId, List<Integer> brandIds) {
  15 + this.middleSortId = middleSortId;
  16 + this.brandIds = brandIds;
  17 + }
  18 +
  19 + public Integer getMiddleSortId() {
  20 + return middleSortId;
  21 + }
  22 +
  23 + public void setMiddleSortId(Integer middleSortId) {
  24 + this.middleSortId = middleSortId;
  25 + }
  26 +
  27 + public List<Integer> getBrandIds() {
  28 + return brandIds;
  29 + }
  30 +
  31 + public void setBrandIds(List<Integer> brandIds) {
  32 + this.brandIds = brandIds;
  33 + }
  34 +}
  1 +package com.yoho.search.recall.scene.models.personal;
  2 +
  3 +import java.io.Serializable;
  4 +import java.util.List;
  5 +
  6 +/**
  7 + * 页面中的品类-价格带
  8 + */
  9 +public class PageSortPriceArea implements Serializable {
  10 +
  11 + private static final long serialVersionUID = 596977708473811201L;
  12 +
  13 + public PageSortPriceArea() {
  14 + }
  15 +
  16 + public PageSortPriceArea(Integer middleSortId, List<Integer> priceAreas) {
  17 + this.middleSortId = middleSortId;
  18 + this.priceAreas = priceAreas;
  19 + }
  20 +
  21 + private Integer middleSortId;
  22 + private List<Integer> priceAreas;
  23 +
  24 + public Integer getMiddleSortId() {
  25 + return middleSortId;
  26 + }
  27 +
  28 + public void setMiddleSortId(Integer middleSortId) {
  29 + this.middleSortId = middleSortId;
  30 + }
  31 +
  32 + public List<Integer> getPriceAreas() {
  33 + return priceAreas;
  34 + }
  35 +
  36 + public void setPriceAreas(List<Integer> priceAreas) {
  37 + this.priceAreas = priceAreas;
  38 + }
  39 +}
@@ -47,6 +47,7 @@ public class AggCommonHelper { @@ -47,6 +47,7 @@ public class AggCommonHelper {
47 return results; 47 return results;
48 } 48 }
49 49
  50 +
50 /** 51 /**
51 * 获取tophit的聚合结果 52 * 获取tophit的聚合结果
52 * 53 *