Authored by hugufei

向量代码兼容

@@ -28,7 +28,7 @@ public class RecommendBrandAggregation extends AbstractAggregation { @@ -28,7 +28,7 @@ public class RecommendBrandAggregation extends AbstractAggregation {
28 this.simpleFieldAggs = new ArrayList<SimpleFieldAgg>(); 28 this.simpleFieldAggs = new ArrayList<SimpleFieldAgg>();
29 simpleFieldAggs.add(new SimpleFieldAgg(aggName(), ProductIndexEsField.brandId, 300)); 29 simpleFieldAggs.add(new SimpleFieldAgg(aggName(), ProductIndexEsField.brandId, 300));
30 // 构造TopHitOrder 30 // 构造TopHitOrder
31 - if (personalVectorFeatureSearch.getPersonalizedSearch(paramMap) != null) { 31 + if (personalVectorFeatureSearch.queryPersonalizedSearch(paramMap) != null) {
32 topHitOrder = "_score:desc"; 32 topHitOrder = "_score:desc";
33 } 33 }
34 } 34 }
@@ -36,7 +36,7 @@ public class RecommendShopAggregation extends AbstractAggregation { @@ -36,7 +36,7 @@ public class RecommendShopAggregation extends AbstractAggregation {
36 this.simpleFieldAggs = new ArrayList<SimpleFieldAgg>(); 36 this.simpleFieldAggs = new ArrayList<SimpleFieldAgg>();
37 simpleFieldAggs.add(new SimpleFieldAgg(aggName(), ProductIndexEsField.shopId, shopCount)); 37 simpleFieldAggs.add(new SimpleFieldAgg(aggName(), ProductIndexEsField.shopId, shopCount));
38 // 构造topHit排序规则 38 // 构造topHit排序规则
39 - if (personalVectorFeatureSearch.getPersonalizedSearch(paramMap) != null) { 39 + if (personalVectorFeatureSearch.queryPersonalizedSearch(paramMap) != null) {
40 topHitOrder = "_score:desc"; 40 topHitOrder = "_score:desc";
41 } 41 }
42 } 42 }
@@ -6,7 +6,9 @@ import java.util.List; @@ -6,7 +6,9 @@ import java.util.List;
6 import java.util.Map; 6 import java.util.Map;
7 import java.util.stream.Collectors; 7 import java.util.stream.Collectors;
8 8
  9 +import com.yoho.search.base.utils.ConvertUtils;
9 import com.yoho.search.service.recall.config.SpecialShopConstants; 10 import com.yoho.search.service.recall.config.SpecialShopConstants;
  11 +import org.apache.commons.collections.CollectionUtils;
10 import org.apache.commons.collections.MapUtils; 12 import org.apache.commons.collections.MapUtils;
11 import org.apache.commons.lang.StringUtils; 13 import org.apache.commons.lang.StringUtils;
12 import org.elasticsearch.common.lucene.search.function.CombineFunction; 14 import org.elasticsearch.common.lucene.search.function.CombineFunction;
@@ -34,252 +36,257 @@ import com.yoho.search.service.scene.general.ProductCountService; @@ -34,252 +36,257 @@ import com.yoho.search.service.scene.general.ProductCountService;
34 @Component 36 @Component
35 public class FunctionScoreSearchHelper { 37 public class FunctionScoreSearchHelper {
36 38
37 - private static final Logger logger = LoggerFactory.getLogger(FunctionScoreSearchHelper.class); 39 + private static final Logger logger = LoggerFactory.getLogger(FunctionScoreSearchHelper.class);
38 40
39 - @Autowired  
40 - private SearchCommonHelper searchCommonHelper;  
41 - @Autowired  
42 - private PersonalVectorFeatureSearch personalVectorFeatureSearch;  
43 - @Autowired  
44 - private SearchDynamicConfigService dynamicConfig;  
45 - @Autowired  
46 - private SearchScorerFactory searchScorerFactory;  
47 - @Autowired  
48 - private ProductCountService productCountService; 41 + @Autowired
  42 + private SearchCommonHelper searchCommonHelper;
  43 + @Autowired
  44 + private PersonalVectorFeatureSearch personalVectorFeatureSearch;
  45 + @Autowired
  46 + private SearchDynamicConfigService dynamicConfig;
  47 + @Autowired
  48 + private SearchScorerFactory searchScorerFactory;
  49 + @Autowired
  50 + private ProductCountService productCountService;
49 51
50 - // 普通个性化的时间维度  
51 - private static final FirstShelveTimeScore COMMON_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(30, 7, 23);  
52 - // 新品到着的个性化时间维度  
53 - private static final FirstShelveTimeScore NEW_REC_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(4, 1, 3);  
54 - // 模糊搜索的个性化时间维度  
55 - private static final FirstShelveTimeScore FUZZY_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(90, 60, 30); 52 + // 普通个性化的时间维度
  53 + private static final FirstShelveTimeScore COMMON_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(30, 7, 23);
  54 + // 新品到着的个性化时间维度
  55 + private static final FirstShelveTimeScore NEW_REC_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(4, 1, 3);
  56 + // 模糊搜索的个性化时间维度
  57 + private static final FirstShelveTimeScore FUZZY_FIRST_SHELVE_SCORE = new FirstShelveTimeScore(90, 60, 30);
56 58
57 - /**  
58 - * 添加打分规则  
59 - *  
60 - * @param queryBuilder  
61 - * @param boolQueryBuilder  
62 - * @param paramMap  
63 - * @return  
64 - */  
65 - public QueryBuilder buildFunctionScoreQueryBuild(QueryBuilder queryBuilder, BoolQueryBuilder boolQueryBuilder, Map<String, String> paramMap) {  
66 - // 1、构造persionalFilter  
67 - BoolQueryBuilder persionalFilter = this.genPersionalFilter(queryBuilder, boolQueryBuilder);  
68 - // 2、获取打分器  
69 - String pageId = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_PAGEID, "0");  
70 - List<IScorer> scorers = this.getScorers(pageId, persionalFilter, paramMap);  
71 - if (scorers == null || scorers.isEmpty()) {  
72 - return new FunctionScoreQueryBuilder(queryBuilder);  
73 - }  
74 - // 3、构造functionScoreQueryBuilder  
75 - YohoFilterFunctionBuilders yohoFilterFunctionBuilders = new YohoFilterFunctionBuilders();  
76 - for (IScorer iScorer : scorers) {  
77 - if(iScorer!=null){  
78 - iScorer.addScorer(yohoFilterFunctionBuilders);  
79 - }  
80 - }  
81 - FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, yohoFilterFunctionBuilders.getFilterFunctionBuilders());  
82 - // 4、设置打分模式  
83 - functionScoreQueryBuilder.boostMode(CombineFunction.MULTIPLY);  
84 - return functionScoreQueryBuilder;  
85 - } 59 + /**
  60 + * 添加打分规则
  61 + *
  62 + * @param queryBuilder
  63 + * @param boolQueryBuilder
  64 + * @param paramMap
  65 + * @return
  66 + */
  67 + public QueryBuilder buildFunctionScoreQueryBuild(QueryBuilder queryBuilder, BoolQueryBuilder boolQueryBuilder, Map<String, String> paramMap) {
  68 + // 1、构造persionalFilter
  69 + BoolQueryBuilder persionalFilter = this.genPersionalFilter(queryBuilder, boolQueryBuilder);
  70 + // 2、获取打分器
  71 + String pageId = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_PAGEID, "0");
  72 + List<IScorer> scorers = this.getScorers(pageId, persionalFilter, paramMap);
  73 + if (scorers == null || scorers.isEmpty()) {
  74 + return new FunctionScoreQueryBuilder(queryBuilder);
  75 + }
  76 + // 3、构造functionScoreQueryBuilder
  77 + YohoFilterFunctionBuilders yohoFilterFunctionBuilders = new YohoFilterFunctionBuilders();
  78 + for (IScorer iScorer : scorers) {
  79 + if (iScorer != null) {
  80 + iScorer.addScorer(yohoFilterFunctionBuilders);
  81 + }
  82 + }
  83 + FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, yohoFilterFunctionBuilders.getFilterFunctionBuilders());
  84 + // 4、设置打分模式
  85 + functionScoreQueryBuilder.boostMode(CombineFunction.MULTIPLY);
  86 + return functionScoreQueryBuilder;
  87 + }
86 88
87 - private BoolQueryBuilder genPersionalFilter(QueryBuilder queryBuilder, BoolQueryBuilder boolQueryBuilder) {  
88 - BoolQueryBuilder persionalFilter = QueryBuilders.boolQuery();  
89 - if (queryBuilder != null) {  
90 - persionalFilter.must(queryBuilder);  
91 - }  
92 - if (boolQueryBuilder != null) {  
93 - persionalFilter.must(boolQueryBuilder);  
94 - }  
95 - return persionalFilter;  
96 - } 89 + private BoolQueryBuilder genPersionalFilter(QueryBuilder queryBuilder, BoolQueryBuilder boolQueryBuilder) {
  90 + BoolQueryBuilder persionalFilter = QueryBuilders.boolQuery();
  91 + if (queryBuilder != null) {
  92 + persionalFilter.must(queryBuilder);
  93 + }
  94 + if (boolQueryBuilder != null) {
  95 + persionalFilter.must(boolQueryBuilder);
  96 + }
  97 + return persionalFilter;
  98 + }
97 99
98 - private List<IScorer> getScorers(String pageId, BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
99 - List<IScorer> scorers = null;  
100 - switch (pageId) {  
101 - case SearchPageIdDefine.PAGE_ID_SORT:  
102 - scorers = this.getSortPageScorers(persionalFilter, paramMap);  
103 - break;  
104 - case SearchPageIdDefine.PAGE_ID_SEARCH:  
105 - scorers = this.getFuzzyPageScorers(persionalFilter, paramMap);  
106 - break;  
107 - case SearchPageIdDefine.PAGE_ID_NEW:  
108 - scorers = this.getNewArrivePageScorers(persionalFilter, paramMap);  
109 - break;  
110 - default:  
111 - scorers = this.getOtherPageScorers(persionalFilter, paramMap);  
112 - break;  
113 - }  
114 - return scorers;  
115 - } 100 + private List<IScorer> getScorers(String pageId, BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  101 + List<IScorer> scorers = null;
  102 + switch (pageId) {
  103 + case SearchPageIdDefine.PAGE_ID_SORT:
  104 + scorers = this.getSortPageScorers(persionalFilter, paramMap);
  105 + break;
  106 + case SearchPageIdDefine.PAGE_ID_SEARCH:
  107 + scorers = this.getFuzzyPageScorers(persionalFilter, paramMap);
  108 + break;
  109 + case SearchPageIdDefine.PAGE_ID_NEW:
  110 + scorers = this.getNewArrivePageScorers(persionalFilter, paramMap);
  111 + break;
  112 + default:
  113 + scorers = this.getOtherPageScorers(persionalFilter, paramMap);
  114 + break;
  115 + }
  116 + return scorers;
  117 + }
116 118
117 - // 品类页的打分器  
118 - private List<IScorer> getSortPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
119 - List<IScorer> scorers = new ArrayList<IScorer>();  
120 - // 1、不是默认品类页,返回空列表  
121 - if (!searchCommonHelper.isSortPageDefault(paramMap)) {  
122 - return scorers;  
123 - }  
124 - // 2、获取通用打分器  
125 - scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));  
126 - // 3、添加首次上架时间的打分器  
127 - scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getOtherPageShelveTimeScore()));  
128 - // 4、品类页添加加分SKN的打分器  
129 - scorers.add(searchScorerFactory.getAddScoreSknsScorer());  
130 - return scorers;  
131 - }  
132 - 119 + // 品类页的打分器
  120 + private List<IScorer> getSortPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  121 + List<IScorer> scorers = new ArrayList<IScorer>();
  122 + // 1、不是默认品类页,返回空列表
  123 + if (!searchCommonHelper.isSortPageDefault(paramMap)) {
  124 + return scorers;
  125 + }
  126 + // 2、获取通用打分器
  127 + scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));
  128 + // 3、添加首次上架时间的打分器
  129 + scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getOtherPageShelveTimeScore()));
  130 + // 4、品类页添加加分SKN的打分器
  131 + scorers.add(searchScorerFactory.getAddScoreSknsScorer());
  132 + return scorers;
  133 + }
133 134
134 - // 模糊搜索页的打分器  
135 - private List<IScorer> getFuzzyPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
136 - List<IScorer> scorers = new ArrayList<>();  
137 - // 1、不是默认搜索类页,返回空列表  
138 - if (!searchCommonHelper.isFuzzySearchPageDefault(paramMap)) {  
139 - return scorers;  
140 - }  
141 - // 2、获取通用打分器  
142 - scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));  
143 - // 3、添加首次上架时间的打分器  
144 - scorers.add(searchScorerFactory.getFirstShelveTimeScorer(FUZZY_FIRST_SHELVE_SCORE));  
145 - // 4、添加频道搜索  
146 - scorers.add(searchScorerFactory.getChannelSearchScorer(paramMap));  
147 - // 5、添加线下可售商品打分器  
148 - scorers.add(searchScorerFactory.getOfflineSaleOnlyScorer());  
149 - // 6、添加关键词完全匹配的打分器  
150 - String query = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY);  
151 - if(StringUtils.isNotBlank(query)){  
152 - scorers.add(searchScorerFactory.getCsBrandKeyWordScorer(query));  
153 - }  
154 - // 7、添加特殊店铺的打分器  
155 - scorers.add(searchScorerFactory.getSpecialShopScorer(SpecialShopConstants.DOWNGRADE_SHOPIDS, SpecialShopConstants.DOWNGRADE_SHOP_WEIGHT));  
156 - return scorers;  
157 - }  
158 135
159 - // 新品到着页的打分器  
160 - private List<IScorer> getNewArrivePageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
161 - List<IScorer> scorers = new ArrayList<IScorer>();  
162 - if (searchCommonHelper.isNewRecPageDefault(paramMap)) {  
163 - scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));  
164 - scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getNewArrivalPageShelveTimeScore()));  
165 - } else if (searchCommonHelper.isNewRecHeatValueDescSearch(paramMap)) {  
166 - scorers.add(searchScorerFactory.getNewArriveHeatDescScorer());// 新品到着页的人气值排序  
167 - }  
168 - return scorers;  
169 - } 136 + // 模糊搜索页的打分器
  137 + private List<IScorer> getFuzzyPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  138 + List<IScorer> scorers = new ArrayList<>();
  139 + // 1、不是默认搜索类页,返回空列表
  140 + if (!searchCommonHelper.isFuzzySearchPageDefault(paramMap)) {
  141 + return scorers;
  142 + }
  143 + // 2、获取通用打分器
  144 + scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));
  145 + // 3、添加首次上架时间的打分器
  146 + scorers.add(searchScorerFactory.getFirstShelveTimeScorer(FUZZY_FIRST_SHELVE_SCORE));
  147 + // 4、添加频道搜索
  148 + scorers.add(searchScorerFactory.getChannelSearchScorer(paramMap));
  149 + // 5、添加线下可售商品打分器
  150 + scorers.add(searchScorerFactory.getOfflineSaleOnlyScorer());
  151 + // 6、添加关键词完全匹配的打分器
  152 + String query = MapUtils.getString(paramMap, SearchRequestParams.PARAM_SEARCH_QUERY);
  153 + if (StringUtils.isNotBlank(query)) {
  154 + scorers.add(searchScorerFactory.getCsBrandKeyWordScorer(query));
  155 + }
  156 + // 7、添加特殊店铺的打分器
  157 + scorers.add(searchScorerFactory.getSpecialShopScorer(SpecialShopConstants.DOWNGRADE_SHOPIDS, SpecialShopConstants.DOWNGRADE_SHOP_WEIGHT));
  158 + return scorers;
  159 + }
170 160
171 - /**  
172 - * 其他页面的打分规则  
173 - *  
174 - * @param persionalFilter  
175 - * @param paramMap  
176 - */  
177 - private List<IScorer> getOtherPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
178 - List<IScorer> scorers = new ArrayList<IScorer>();  
179 - if (!searchCommonHelper.isOrderEmpty(paramMap)) {  
180 - return scorers;  
181 - }  
182 - scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));  
183 - scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getOtherPageShelveTimeScore()));  
184 - return scorers;  
185 - } 161 + // 新品到着页的打分器
  162 + private List<IScorer> getNewArrivePageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  163 + List<IScorer> scorers = new ArrayList<IScorer>();
  164 + if (searchCommonHelper.isNewRecPageDefault(paramMap)) {
  165 + scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));
  166 + scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getNewArrivalPageShelveTimeScore()));
  167 + } else if (searchCommonHelper.isNewRecHeatValueDescSearch(paramMap)) {
  168 + scorers.add(searchScorerFactory.getNewArriveHeatDescScorer());// 新品到着页的人气值排序
  169 + }
  170 + return scorers;
  171 + }
186 172
187 - // 公用的打分器  
188 - private List<IScorer> getCommonScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
189 - // 1、传了order,则都不生效  
190 - if (!searchCommonHelper.isOrderEmpty(paramMap)) {  
191 - return new ArrayList<IScorer>();  
192 - }  
193 - List<IScorer> scorers = new ArrayList<IScorer>();  
194 - // 2、全球购商品  
195 - scorers.add(searchScorerFactory.getGlobalProductSearch(paramMap));  
196 - // 3、一高三低商品降分[非新品并且零交际的商品]  
197 - scorers.add(searchScorerFactory.getProblemProductScorer());  
198 - // 4、first_product_skn  
199 - scorers.add(searchScorerFactory.getFirstProductSknScorer(paramMap));  
200 - // 5、断码商品  
201 - //scorers.add(searchScorerFactory.getBreakSizeProductScorer(paramMap));  
202 - // 6、基于向量的个性化打分  
203 - scorers.add(this.getPersonalVectorFeatureScorer(persionalFilter, paramMap));  
204 - return scorers;  
205 - } 173 + /**
  174 + * 其他页面的打分规则
  175 + *
  176 + * @param persionalFilter
  177 + * @param paramMap
  178 + */
  179 + private List<IScorer> getOtherPageScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  180 + List<IScorer> scorers = new ArrayList<IScorer>();
  181 + if (!searchCommonHelper.isOrderEmpty(paramMap)) {
  182 + return scorers;
  183 + }
  184 + scorers.addAll(this.getCommonScorers(persionalFilter, paramMap));
  185 + scorers.add(searchScorerFactory.getFirstShelveTimeScorer(getOtherPageShelveTimeScore()));
  186 + return scorers;
  187 + }
206 188
207 - /**  
208 - * 个性化的打分器  
209 - *  
210 - * @param persionalFilter  
211 - * @param paramMap  
212 - * @return  
213 - */  
214 - private IScorer getPersonalVectorFeatureScorer(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {  
215 - // 1、判断是否开启了个性化搜索  
216 - if (!searchCommonHelper.isNeedPersonalSearch(paramMap)) {  
217 - return null;  
218 - }  
219 - // 2、获取PersonalizedSearch  
220 - PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.getPersonalizedSearch(paramMap);  
221 - if (personalizedSearch == null) {  
222 - return null;  
223 - }  
224 - // 3、为个性化打分添加filter条件  
225 - BoolQueryBuilder scoreFilter = productCountService.genScoreFilter(persionalFilter);  
226 - return searchScorerFactory.getFeatureFactorScorer(scoreFilter, personalizedSearch.getUserVectorFeature(), personalizedSearch.getVectorFeatureVersion());  
227 - } 189 + // 公用的打分器
  190 + private List<IScorer> getCommonScorers(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  191 + // 1、传了order,则都不生效
  192 + if (!searchCommonHelper.isOrderEmpty(paramMap)) {
  193 + return new ArrayList<IScorer>();
  194 + }
  195 + List<IScorer> scorers = new ArrayList<IScorer>();
  196 + // 2、全球购商品
  197 + scorers.add(searchScorerFactory.getGlobalProductSearch(paramMap));
  198 + // 3、一高三低商品降分[非新品并且零交际的商品]
  199 + scorers.add(searchScorerFactory.getProblemProductScorer());
  200 + // 4、first_product_skn
  201 + scorers.add(searchScorerFactory.getFirstProductSknScorer(paramMap));
  202 + // 5、断码商品
  203 + //scorers.add(searchScorerFactory.getBreakSizeProductScorer(paramMap));
  204 + // 6、基于向量的个性化打分
  205 + scorers.add(this.getPersonalVectorFeatureScorer(persionalFilter, paramMap));
  206 + return scorers;
  207 + }
228 208
229 - /**  
230 - * 直接使用商品特征的向量用来做个性化打分  
231 - *  
232 - * @param queryBuilder  
233 - * @param productVectorFeature  
234 - * @return  
235 - */  
236 - public QueryBuilder buildFunctionScoreQueryBuildWithProductFeature(QueryBuilder queryBuilder, String productVectorFeature) {  
237 - // 1. 获取商品特征向量  
238 - if (StringUtils.isBlank(productVectorFeature)) {  
239 - return queryBuilder;  
240 - }  
241 - // 2. 传入参数调用脚本,以商品特征代替用户特征  
242 - String[] productVectorFeatures = productVectorFeature.split("\\|", 2);  
243 - if (productVectorFeatures.length != 2) {  
244 - return queryBuilder;  
245 - }  
246 - IScorer scorer = searchScorerFactory.getFeatureFactorScorer(queryBuilder, productVectorFeatures[1], productVectorFeatures[0]);  
247 - YohoFilterFunctionBuilders yohoFilterFunctionBuilders = new YohoFilterFunctionBuilders();  
248 - if(scorer!=null){  
249 - scorer.addScorer(yohoFilterFunctionBuilders);  
250 - }  
251 - FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder,yohoFilterFunctionBuilders.getFilterFunctionBuilders());  
252 - return functionScoreQueryBuilder;  
253 - } 209 + /**
  210 + * 个性化的打分器
  211 + *
  212 + * @param persionalFilter
  213 + * @param paramMap
  214 + * @return
  215 + */
  216 + private IScorer getPersonalVectorFeatureScorer(BoolQueryBuilder persionalFilter, Map<String, String> paramMap) {
  217 + // 1、判断是否开启了个性化搜索
  218 + if (!searchCommonHelper.isNeedPersonalSearch(paramMap)) {
  219 + return null;
  220 + }
  221 + // 2、获取PersonalizedSearch
  222 + PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.queryPersonalizedSearch(paramMap);
  223 + if (personalizedSearch == null) {
  224 + return null;
  225 + }
  226 + // 3、为个性化打分添加filter条件
  227 + BoolQueryBuilder scoreFilter = productCountService.genScoreFilter(persionalFilter);
  228 + return searchScorerFactory.getFeatureFactorScorer(scoreFilter, personalizedSearch.getVectorVersion(), personalizedSearch.getVectorFeatures());
  229 + }
254 230
255 - // 新品到着页的根据首次上架时间衰减函数规则值  
256 - private FirstShelveTimeScore getNewArrivalPageShelveTimeScore() {  
257 - try {  
258 - String values = dynamicConfig.getNewArrivalPageDecayRuleValue();  
259 - List<Integer> valueList = Arrays.asList(values.split(",")).stream().map(Integer::valueOf).collect(Collectors.toList());  
260 - Assert.isTrue(valueList.size() == 2, "For " + values);  
261 - Integer scale = valueList.get(0) - valueList.get(1);  
262 - Assert.isTrue(scale.intValue() > 0, "For " + values);  
263 - return new FirstShelveTimeScore(valueList.get(0), valueList.get(1), scale);  
264 - } catch (Exception e) {  
265 - logger.warn(e.getMessage(), e);  
266 - return NEW_REC_FIRST_SHELVE_SCORE;  
267 - }  
268 - } 231 + /**
  232 + * 直接使用商品特征的向量用来做个性化打分
  233 + *
  234 + * @param queryBuilder
  235 + * @param productVectorFeature
  236 + * @return
  237 + */
  238 + public QueryBuilder buildFunctionScoreQueryBuildWithProductFeature(QueryBuilder queryBuilder, String productVectorFeature) {
  239 + // 1. 获取商品特征向量
  240 + if (StringUtils.isBlank(productVectorFeature)) {
  241 + return queryBuilder;
  242 + }
  243 + // 2. 传入参数调用脚本,以商品特征代替用户特征
  244 + String[] productVectorFeatures = productVectorFeature.split("\\|", 2);
  245 + if (productVectorFeatures.length != 2) {
  246 + return queryBuilder;
  247 + }
  248 + // 3、参数检测
  249 + String featureVersion = productVectorFeatures[0];
  250 + List<Double> featureFactors = ConvertUtils.stringToDoubleList(productVectorFeatures[1], ",");
  251 + if (StringUtils.isBlank(featureVersion) || CollectionUtils.isEmpty(featureFactors)) {
  252 + return queryBuilder;
  253 + }
  254 + //4、构造scorer
  255 + IScorer scorer = searchScorerFactory.getFeatureFactorScorer(queryBuilder, featureVersion, featureFactors);
  256 + YohoFilterFunctionBuilders yohoFilterFunctionBuilders = new YohoFilterFunctionBuilders();
  257 + scorer.addScorer(yohoFilterFunctionBuilders);
  258 + FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder, yohoFilterFunctionBuilders.getFilterFunctionBuilders());
  259 + return functionScoreQueryBuilder;
  260 + }
269 261
270 - // 非新品到着页的根据首次上架时间衰减函数规则值  
271 - private FirstShelveTimeScore getOtherPageShelveTimeScore() {  
272 - try {  
273 - String values = dynamicConfig.getOtherPageDecayRuleValue();  
274 - List<Integer> valueList = Arrays.asList(values.split(",")).stream().map(Integer::valueOf).collect(Collectors.toList());  
275 - Assert.isTrue(valueList.size() == 2, "For " + values);  
276 - Integer scale = valueList.get(0) - valueList.get(1);  
277 - Assert.isTrue(scale.intValue() > 0, "For " + values);  
278 - return new FirstShelveTimeScore(valueList.get(0), valueList.get(1), scale);  
279 - } catch (Exception e) {  
280 - logger.warn(e.getMessage(), e);  
281 - return COMMON_FIRST_SHELVE_SCORE;  
282 - }  
283 - } 262 + // 新品到着页的根据首次上架时间衰减函数规则值
  263 + private FirstShelveTimeScore getNewArrivalPageShelveTimeScore() {
  264 + try {
  265 + String values = dynamicConfig.getNewArrivalPageDecayRuleValue();
  266 + List<Integer> valueList = Arrays.asList(values.split(",")).stream().map(Integer::valueOf).collect(Collectors.toList());
  267 + Assert.isTrue(valueList.size() == 2, "For " + values);
  268 + Integer scale = valueList.get(0) - valueList.get(1);
  269 + Assert.isTrue(scale.intValue() > 0, "For " + values);
  270 + return new FirstShelveTimeScore(valueList.get(0), valueList.get(1), scale);
  271 + } catch (Exception e) {
  272 + logger.warn(e.getMessage(), e);
  273 + return NEW_REC_FIRST_SHELVE_SCORE;
  274 + }
  275 + }
  276 +
  277 + // 非新品到着页的根据首次上架时间衰减函数规则值
  278 + private FirstShelveTimeScore getOtherPageShelveTimeScore() {
  279 + try {
  280 + String values = dynamicConfig.getOtherPageDecayRuleValue();
  281 + List<Integer> valueList = Arrays.asList(values.split(",")).stream().map(Integer::valueOf).collect(Collectors.toList());
  282 + Assert.isTrue(valueList.size() == 2, "For " + values);
  283 + Integer scale = valueList.get(0) - valueList.get(1);
  284 + Assert.isTrue(scale.intValue() > 0, "For " + values);
  285 + return new FirstShelveTimeScore(valueList.get(0), valueList.get(1), scale);
  286 + } catch (Exception e) {
  287 + logger.warn(e.getMessage(), e);
  288 + return COMMON_FIRST_SHELVE_SCORE;
  289 + }
  290 + }
284 291
285 } 292 }
@@ -182,7 +182,7 @@ public class UserRecallResponseBuilder { @@ -182,7 +182,7 @@ public class UserRecallResponseBuilder {
182 //1、获取用户向量 182 //1、获取用户向量
183 Map<String, String> paramMap = new HashMap<>(); 183 Map<String, String> paramMap = new HashMap<>();
184 paramMap.put("uid", "" + uid); 184 paramMap.put("uid", "" + uid);
185 - PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.getPersonalizedSearch(paramMap); 185 + PersonalizedSearch personalizedSearch = personalVectorFeatureSearch.queryPersonalizedSearch(paramMap);
186 UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch); 186 UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch);
187 //2、计算相关性 187 //2、计算相关性
188 int recommendSknIndex = 10000; 188 int recommendSknIndex = 10000;
1 package com.yoho.search.service.recall.beans.persional; 1 package com.yoho.search.service.recall.beans.persional;
2 2
3 import com.yoho.search.base.helper.Word2VectorCalculator; 3 import com.yoho.search.base.helper.Word2VectorCalculator;
  4 +import com.yoho.search.base.utils.ConvertUtils;
4 import com.yoho.search.core.personalized.models.PersonalizedSearch; 5 import com.yoho.search.core.personalized.models.PersonalizedSearch;
5 import com.yoho.search.service.recall.models.personal.UserFeatureFactor; 6 import com.yoho.search.service.recall.models.personal.UserFeatureFactor;
  7 +import org.apache.commons.collections.CollectionUtils;
6 import org.apache.commons.lang.StringUtils; 8 import org.apache.commons.lang.StringUtils;
7 import org.slf4j.Logger; 9 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory; 10 import org.slf4j.LoggerFactory;
9 import org.springframework.stereotype.Component; 11 import org.springframework.stereotype.Component;
10 12
11 -import java.util.ArrayList;  
12 import java.util.List; 13 import java.util.List;
13 14
14 @Component 15 @Component
@@ -21,23 +22,28 @@ public class ProductFeatureFactorComponent { @@ -21,23 +22,28 @@ public class ProductFeatureFactorComponent {
21 22
22 public double calProductFeatureFactor(UserFeatureFactor userFeatureFactor, String productFeatureFactor) { 23 public double calProductFeatureFactor(UserFeatureFactor userFeatureFactor, String productFeatureFactor) {
23 try { 24 try {
  25 + //商品向量不存在,则返回
  26 + if (StringUtils.isBlank(productFeatureFactor)) {
  27 + return 0;
  28 + }
24 //用户向量不存在,则返回0 29 //用户向量不存在,则返回0
25 - if (userFeatureFactor == null || StringUtils.isBlank(userFeatureFactor.getVectorFeatureVersion())) { 30 + if (userFeatureFactor == null || StringUtils.isBlank(userFeatureFactor.getVectorVersion())) {
26 return 0; 31 return 0;
27 } 32 }
28 - if (StringUtils.isBlank(productFeatureFactor)) { 33 + if (CollectionUtils.isEmpty(userFeatureFactor.getVectorFeatureList())) {
29 return 0; 34 return 0;
30 } 35 }
31 - String versionPrefix = userFeatureFactor.getVectorFeatureVersion() + "|"; 36 + //版本不匹配,则返回0
  37 + String versionPrefix = userFeatureFactor.getVectorVersion() + "|";
32 if (!productFeatureFactor.trim().startsWith(versionPrefix)) { 38 if (!productFeatureFactor.trim().startsWith(versionPrefix)) {
33 return 0; 39 return 0;
34 } 40 }
35 - String[] productFeatureFactorArr = productFeatureFactor.trim().substring(versionPrefix.length()).split(",");  
36 - List<Double> productFeatureVectors = this.arrayToList(productFeatureFactorArr);  
37 - if (productFeatureVectors == null || productFeatureVectors.size() != userFeatureFactor.getUserFeatureVectorList().size()) { 41 + //执行计算
  42 + List<Double> productFeatureVectors = ConvertUtils.stringToDoubleList(productFeatureFactor.trim().substring(versionPrefix.length()), ",");
  43 + if (productFeatureVectors == null || productFeatureVectors.size() != userFeatureFactor.getVectorFeatureList().size()) {
38 return 0; 44 return 0;
39 } 45 }
40 - double score = Word2VectorCalculator.calScore(userFeatureFactor.getUserFeatureVectorList(), userFeatureFactor.getUserFeatureVectorNorm(), productFeatureVectors); 46 + double score = Word2VectorCalculator.calScore(userFeatureFactor.getVectorFeatureList(), userFeatureFactor.getUserFeatureVectorNorm(), productFeatureVectors);
41 double finalScore = baseConstant + factorConstant * score; 47 double finalScore = baseConstant + factorConstant * score;
42 return finalScore; 48 return finalScore;
43 } catch (Exception e) { 49 } catch (Exception e) {
@@ -46,22 +52,12 @@ public class ProductFeatureFactorComponent { @@ -46,22 +52,12 @@ public class ProductFeatureFactorComponent {
46 } 52 }
47 } 53 }
48 54
49 - private List<Double> arrayToList(String[] productFeatureFactorStrArr) {  
50 - List<Double> results = new ArrayList<>();  
51 - if (productFeatureFactorStrArr == null) {  
52 - return results;  
53 - }  
54 - for (String productFeatureFactor : productFeatureFactorStrArr) {  
55 - results.add(Double.parseDouble(productFeatureFactor));  
56 - }  
57 - return results;  
58 - }  
59 -  
60 public static void main(String[] args) { 55 public static void main(String[] args) {
61 - PersonalizedSearch personalizedSearch = new PersonalizedSearch("1", "20180408", "0.342045,-0.547933,0.291732,-0.056515,-0.182701,0.31113,0.151578,0.087678,-0.045536,-0.525699,-0.394715,-0.103153,-0.05575,-0.540641,0.028046,-0.193109,-0.003591,0.180923,0.290261,0.532309,-0.202463,-0.047271,-0.246197,0.324561,0.188814,0.36475,0.079007,0.455753,-0.11848,-0.135874,-0.187155,-0.055342,-0.12525,0.210669,-0.388331,-0.197123,0.132309,-0.4231,0.217752,-0.203266,0.190836,0.373428,-0.0102,-0.038654,0.2379,0.044424,0.071826,-0.201054,0.257434,0.141901,-0.390064,0.437099,0.559701,-0.040162,-0.193089,0.442338,-0.141678,-0.049696,0.315545,-0.028972,0.278694,-0.064345,-0.327943,0.103025,-0.40344,-0.34269,-0.237931,0.287046,0.139693,-0.38454,0.019959,-0.156907,0.374996,-0.074558,-0.019391,0.050522,0.315171,0.211605,-0.15418,0.502362,0.10184,0.153274,0.592659,-0.010284,0.28029,0.319741,-0.164559,0.286884,0.420483,-0.628866,-0.172259,0.027954,-0.411674,0.376585,0.322832,0.352039,0.078705,0.045152,0.139083,-0.164182"); 56 + List<Double> array = ConvertUtils.stringToDoubleList("0.342045,-0.547933,0.291732,-0.056515,-0.182701,0.31113,0.151578,0.087678,-0.045536,-0.525699,-0.394715,-0.103153,-0.05575,-0.540641,0.028046,-0.193109,-0.003591,0.180923,0.290261,0.532309,-0.202463,-0.047271,-0.246197,0.324561,0.188814,0.36475,0.079007,0.455753,-0.11848,-0.135874,-0.187155,-0.055342,-0.12525,0.210669,-0.388331,-0.197123,0.132309,-0.4231,0.217752,-0.203266,0.190836,0.373428,-0.0102,-0.038654,0.2379,0.044424,0.071826,-0.201054,0.257434,0.141901,-0.390064,0.437099,0.559701,-0.040162,-0.193089,0.442338,-0.141678,-0.049696,0.315545,-0.028972,0.278694,-0.064345,-0.327943,0.103025,-0.40344,-0.34269,-0.237931,0.287046,0.139693,-0.38454,0.019959,-0.156907,0.374996,-0.074558,-0.019391,0.050522,0.315171,0.211605,-0.15418,0.502362,0.10184,0.153274,0.592659,-0.010284,0.28029,0.319741,-0.164559,0.286884,0.420483,-0.628866,-0.172259,0.027954,-0.411674,0.376585,0.322832,0.352039,0.078705,0.045152,0.139083,-0.164182", ",");
  57 + PersonalizedSearch personalizedSearch = new PersonalizedSearch("1", "20180408", array);
62 UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch); 58 UserFeatureFactor userFeatureFactor = new UserFeatureFactor(personalizedSearch);
63 - String productFeatureFactor = "20180408|0.342045,-0.547933,0.291732,-0.056515,-0.182701,0.31113,0.151578,0.087678,-0.045536,-0.525699,-0.394715,-0.103153,-0.05575,-0.540641,0.028046,-0.193109,-0.003591,0.180923,0.290261,0.532309,-0.202463,-0.047271,-0.246197,0.324561,0.188814,0.36475,0.079007,0.455753,-0.11848,-0.135874,-0.187155,-0.055342,-0.12525,0.210669,-0.388331,-0.197123,0.132309,-0.4231,0.217752,-0.203266,0.190836,0.373428,-0.0102,-0.038654,0.2379,0.044424,0.071826,-0.201054,0.257434,0.141901,-0.390064,0.437099,0.559701,-0.040162,-0.193089,0.442338,-0.141678,-0.049696,0.315545,-0.028972,0.278694,-0.064345,-0.327943,0.103025,-0.40344,-0.34269,-0.237931,0.287046,0.139693,-0.38454,0.019959,-0.156907,0.374996,-0.074558,-0.019391,0.050522,0.315171,0.211605,-0.15418,0.502362,0.10184,0.153274,0.592659,-0.010284,0.28029,0.319741,-0.164559,0.286884,0.420483,-0.628866,-0.172259,0.027954,-0.411674,0.376585,0.322832,0.352039,0.078705,0.045152,0.139083,-0.164182";  
64 - System.out.println(new ProductFeatureFactorComponent().calProductFeatureFactor(userFeatureFactor,productFeatureFactor)); 59 + String productFeatureFactor = "20180408|1.342045,-0.547933,0.291732,-0.056515,-0.182701,0.31113,0.151578,0.087678,-0.045536,-0.525699,-0.394715,-0.103153,-0.05575,-0.540641,0.028046,-0.193109,-0.003591,0.180923,0.290261,0.532309,-0.202463,-0.047271,-0.246197,0.324561,0.188814,0.36475,0.079007,0.455753,-0.11848,-0.135874,-0.187155,-0.055342,-0.12525,0.210669,-0.388331,-0.197123,0.132309,-0.4231,0.217752,-0.203266,0.190836,0.373428,-0.0102,-0.038654,0.2379,0.044424,0.071826,-0.201054,0.257434,0.141901,-0.390064,0.437099,0.559701,-0.040162,-0.193089,0.442338,-0.141678,-0.049696,0.315545,-0.028972,0.278694,-0.064345,-0.327943,0.103025,-0.40344,-0.34269,-0.237931,0.287046,0.139693,-0.38454,0.019959,-0.156907,0.374996,-0.074558,-0.019391,0.050522,0.315171,0.211605,-0.15418,0.502362,0.10184,0.153274,0.592659,-0.010284,0.28029,0.319741,-0.164559,0.286884,0.420483,-0.628866,-0.172259,0.027954,-0.411674,0.376585,0.322832,0.352039,0.078705,0.045152,0.139083,-0.164182";
  60 + System.out.println(new ProductFeatureFactorComponent().calProductFeatureFactor(userFeatureFactor, productFeatureFactor));
65 } 61 }
66 62
67 } 63 }
1 package com.yoho.search.service.recall.models.personal; 1 package com.yoho.search.service.recall.models.personal;
2 2
3 import com.yoho.search.core.personalized.models.PersonalizedSearch; 3 import com.yoho.search.core.personalized.models.PersonalizedSearch;
4 -import org.apache.commons.lang.StringUtils; 4 +import org.apache.commons.collections.CollectionUtils;
5 import org.slf4j.Logger; 5 import org.slf4j.Logger;
6 import org.slf4j.LoggerFactory; 6 import org.slf4j.LoggerFactory;
7 7
8 -import java.util.ArrayList;  
9 import java.util.List; 8 import java.util.List;
10 9
11 public class UserFeatureFactor { 10 public class UserFeatureFactor {
12 11
13 - private static final Logger logger = LoggerFactory.getLogger(UserFeatureFactor.class);  
14 -  
15 - private List<Double> userFeatureVectorList = null;  
16 - private double userFeatureVectorNorm = 0.0D;  
17 - private String vectorFeatureVersion;  
18 -  
19 - public UserFeatureFactor(PersonalizedSearch personalizedSearch) {  
20 - try {  
21 - if (personalizedSearch == null) {  
22 - return;  
23 - }  
24 - this.vectorFeatureVersion = personalizedSearch.getVectorFeatureVersion();  
25 - String userVectorFeature = personalizedSearch.getUserVectorFeature();  
26 - if(StringUtils.isBlank(userVectorFeature)){  
27 - return;  
28 - }  
29 - String[] userFeatureFactorStrArr = userVectorFeature.split(",");  
30 - if(userFeatureFactorStrArr.length==0){  
31 - return;  
32 - }  
33 - userFeatureVectorList = new ArrayList<>(userFeatureFactorStrArr.length);  
34 - for (String userFeatureFactorStr : userFeatureFactorStrArr) {  
35 - double userFeatureVector = Double.parseDouble(userFeatureFactorStr.trim());  
36 - userFeatureVectorList.add(userFeatureVector);  
37 - userFeatureVectorNorm += userFeatureVector * userFeatureVector;  
38 - }  
39 - }catch (Exception e){  
40 - logger.error(e.getMessage());  
41 - }  
42 - }  
43 -  
44 - public List<Double> getUserFeatureVectorList() {  
45 - return userFeatureVectorList;  
46 - }  
47 -  
48 - public double getUserFeatureVectorNorm() {  
49 - return userFeatureVectorNorm;  
50 - }  
51 -  
52 - public String getVectorFeatureVersion() {  
53 - return vectorFeatureVersion;  
54 - } 12 + private static final Logger logger = LoggerFactory.getLogger(UserFeatureFactor.class);
  13 +
  14 + private String vectorVersion;
  15 + private List<Double> vectorFeatureList = null;
  16 + private double userFeatureVectorNorm = 0.0D;
  17 +
  18 + public UserFeatureFactor(PersonalizedSearch personalizedSearch) {
  19 + try {
  20 + if (personalizedSearch == null) {
  21 + return;
  22 + }
  23 + this.vectorVersion = personalizedSearch.getVectorVersion();
  24 + this.vectorFeatureList = personalizedSearch.getVectorFeatures();
  25 + if (CollectionUtils.isEmpty(vectorFeatureList)) {
  26 + return;
  27 + }
  28 + for (Double vectorFeature : vectorFeatureList) {
  29 + userFeatureVectorNorm += vectorFeature * vectorFeature;
  30 + }
  31 + } catch (Exception e) {
  32 + logger.error(e.getMessage());
  33 + }
  34 + }
  35 +
  36 + public String getVectorVersion() {
  37 + return vectorVersion;
  38 + }
  39 +
  40 + public List<Double> getVectorFeatureList() {
  41 + return vectorFeatureList;
  42 + }
  43 +
  44 + public double getUserFeatureVectorNorm() {
  45 + return userFeatureVectorNorm;
  46 + }
  47 +
55 } 48 }
@@ -102,8 +102,8 @@ public class SearchScorerFactory { @@ -102,8 +102,8 @@ public class SearchScorerFactory {
102 } 102 }
103 103
104 // 获取【向量余弦夹角】的打分器 104 // 获取【向量余弦夹角】的打分器
105 - public IScorer getFeatureFactorScorer(QueryBuilder scoreFilter, String featureFactors, String featureVersion) {  
106 - return new FeatureFactorScorer(scoreFilter, featureFactors, featureVersion); 105 + public IScorer getFeatureFactorScorer(QueryBuilder scoreFilter,String featureVersion, List<Double> featureFactors) {
  106 + return new FeatureFactorScorer(scoreFilter,featureVersion,featureFactors);
107 } 107 }
108 108
109 public IScorer getOfflineSaleOnlyScorer() { 109 public IScorer getOfflineSaleOnlyScorer() {
1 package com.yoho.search.service.scorer.impl; 1 package com.yoho.search.service.scorer.impl;
2 2
3 import java.util.HashMap; 3 import java.util.HashMap;
  4 +import java.util.List;
4 import java.util.Map; 5 import java.util.Map;
5 6
  7 +import org.apache.commons.collections.CollectionUtils;
  8 +import org.apache.commons.lang.StringUtils;
6 import org.elasticsearch.index.query.QueryBuilder; 9 import org.elasticsearch.index.query.QueryBuilder;
7 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; 10 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
8 import org.elasticsearch.script.Script; 11 import org.elasticsearch.script.Script;
@@ -21,22 +24,22 @@ public class FeatureFactorScorer implements IScorer { @@ -21,22 +24,22 @@ public class FeatureFactorScorer implements IScorer {
21 private static final Double FACTOR_CONSTANT = 0.4D; 24 private static final Double FACTOR_CONSTANT = 0.4D;
22 25
23 private QueryBuilder scoreFilter; 26 private QueryBuilder scoreFilter;
24 - private String featureFactors;  
25 private String featureVersion; 27 private String featureVersion;
  28 + private String featureFactorString;
26 29
27 - public FeatureFactorScorer(QueryBuilder scoreFilter, String featureFactors, String featureVersion) { 30 + public FeatureFactorScorer(QueryBuilder scoreFilter, String featureVersion,List<Double> featureFactors) {
28 super(); 31 super();
29 this.scoreFilter = scoreFilter; 32 this.scoreFilter = scoreFilter;
30 - this.featureFactors = featureFactors;  
31 this.featureVersion = featureVersion; 33 this.featureVersion = featureVersion;
  34 + this.featureFactorString = StringUtils.join(featureFactors,",");
32 } 35 }
33 36
34 @Override 37 @Override
35 public void addScorer(YohoFilterFunctionBuilders yohoFilterFunctionBuilders) { 38 public void addScorer(YohoFilterFunctionBuilders yohoFilterFunctionBuilders) {
36 Map<String, Object> scriptParams = new HashMap<>(); 39 Map<String, Object> scriptParams = new HashMap<>();
37 scriptParams.put("field", "productFeatureFactor"); 40 scriptParams.put("field", "productFeatureFactor");
38 - scriptParams.put("userFeatureFactors", featureFactors);  
39 scriptParams.put("vectorFeatureVersion", featureVersion); 41 scriptParams.put("vectorFeatureVersion", featureVersion);
  42 + scriptParams.put("userFeatureFactors", featureFactorString);
40 scriptParams.put("baseConstant", BASE_CONSTANT); 43 scriptParams.put("baseConstant", BASE_CONSTANT);
41 scriptParams.put("factorConstant", FACTOR_CONSTANT); 44 scriptParams.put("factorConstant", FACTOR_CONSTANT);
42 Script script = new Script(ScriptType.INLINE, "native", "feature_factor_vector_score", scriptParams); 45 Script script = new Script(ScriptType.INLINE, "native", "feature_factor_vector_score", scriptParams);
1 package com.yoho.search.service.scorer.personal; 1 package com.yoho.search.service.scorer.personal;
2 2
3 import com.yoho.search.aop.cache.SearchCacheAble; 3 import com.yoho.search.aop.cache.SearchCacheAble;
  4 +import com.yoho.search.base.utils.ConvertUtils;
4 import com.yoho.search.cache.CacheType; 5 import com.yoho.search.cache.CacheType;
5 import com.yoho.search.core.personalized.models.PersonalizedSearch; 6 import com.yoho.search.core.personalized.models.PersonalizedSearch;
6 import com.yoho.search.core.personalized.service.BidataServiceCaller; 7 import com.yoho.search.core.personalized.service.BidataServiceCaller;
7 import com.yoho.search.core.personalized.service.PersonalVersionManager; 8 import com.yoho.search.core.personalized.service.PersonalVersionManager;
  9 +import org.apache.commons.collections.CollectionUtils;
8 import org.apache.commons.lang3.StringUtils; 10 import org.apache.commons.lang3.StringUtils;
9 import org.slf4j.Logger; 11 import org.slf4j.Logger;
10 import org.slf4j.LoggerFactory; 12 import org.slf4j.LoggerFactory;
11 import org.springframework.beans.factory.annotation.Autowired; 13 import org.springframework.beans.factory.annotation.Autowired;
12 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
13 15
  16 +import java.util.List;
14 import java.util.Map; 17 import java.util.Map;
15 18
16 @Service 19 @Service
@@ -23,8 +26,8 @@ public class PersonalVectorFeatureSearch { @@ -23,8 +26,8 @@ public class PersonalVectorFeatureSearch {
23 @Autowired 26 @Autowired
24 private BidataServiceCaller bidataServiceCaller; 27 private BidataServiceCaller bidataServiceCaller;
25 28
26 - @SearchCacheAble(cacheInMinute = 30, cacheName = "PERSIONAL_VECTOR", returnClass = PersonalizedSearch.class, cacheType = CacheType.SEARCH_REDIS, includeParams = { "uid" })  
27 - public PersonalizedSearch getPersonalizedSearch(Map<String, String> paramMap) { 29 + @SearchCacheAble(cacheInMinute = 30, cacheName = "USER_PERSIONAL_VECTOR", returnClass = PersonalizedSearch.class, cacheType = CacheType.SEARCH_REDIS, includeParams = { "uid" })
  30 + public PersonalizedSearch queryPersonalizedSearch(Map<String, String> paramMap) {
28 try { 31 try {
29 // 1、参数校验 32 // 1、参数校验
30 String uid = paramMap.get("uid"); 33 String uid = paramMap.get("uid");
@@ -41,7 +44,11 @@ public class PersonalVectorFeatureSearch { @@ -41,7 +44,11 @@ public class PersonalVectorFeatureSearch {
41 if (StringUtils.isEmpty(userVectorFeature)) { 44 if (StringUtils.isEmpty(userVectorFeature)) {
42 return null; 45 return null;
43 } 46 }
44 - return new PersonalizedSearch(uid, vectorFeatureVersion, userVectorFeature); 47 + List<Double> doubleList = ConvertUtils.stringToDoubleList(userVectorFeature,",");
  48 + if(CollectionUtils.isEmpty(doubleList)){
  49 + return null;
  50 + }
  51 + return new PersonalizedSearch(uid, vectorFeatureVersion, doubleList);
45 } catch (Exception e) { 52 } catch (Exception e) {
46 logger.error(e.getMessage(),e); 53 logger.error(e.getMessage(),e);
47 return null; 54 return null;