Authored by Gino Zhang

通过开关控制个性化采用老的还是新的基于特征向量的

@@ -2,7 +2,7 @@ package com.yoho.search.service.personalized; @@ -2,7 +2,7 @@ package com.yoho.search.service.personalized;
2 2
3 import com.yoho.search.service.service.SearchDynamicConfigService; 3 import com.yoho.search.service.service.SearchDynamicConfigService;
4 import org.apache.commons.lang3.StringUtils; 4 import org.apache.commons.lang3.StringUtils;
5 -import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder; 5 +import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
6 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; 6 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
7 import org.elasticsearch.script.Script; 7 import org.elasticsearch.script.Script;
8 import org.elasticsearch.script.ScriptService; 8 import org.elasticsearch.script.ScriptService;
@@ -30,17 +30,17 @@ public class PersonalVectorFeatureSearch { @@ -30,17 +30,17 @@ public class PersonalVectorFeatureSearch {
30 @Autowired 30 @Autowired
31 private PersonalizedRedisService personalizedRedisService; 31 private PersonalizedRedisService personalizedRedisService;
32 32
33 - public ScoreFunctionBuilder build(String uid) { 33 + public void addPersonalizedScriptScore(FunctionScoreQueryBuilder functionScoreQueryBuilder, String uid) {
34 // 1. 获取特征向量版本(即生成时间,该时间需要与skn的生成时间一致才有意义) 34 // 1. 获取特征向量版本(即生成时间,该时间需要与skn的生成时间一致才有意义)
35 String vectorFeatureVersion = searchDynamicConfigService.personalizedSearchVersion(); 35 String vectorFeatureVersion = searchDynamicConfigService.personalizedSearchVersion();
36 if (StringUtils.isEmpty(vectorFeatureVersion) || "-1".equals(vectorFeatureVersion)) { 36 if (StringUtils.isEmpty(vectorFeatureVersion) || "-1".equals(vectorFeatureVersion)) {
37 - return null; 37 + return;
38 } 38 }
39 39
40 // 2. 获取用户的特征向量 40 // 2. 获取用户的特征向量
41 String userVectorFeature = personalizedRedisService.getUserVectorFeature(uid, vectorFeatureVersion); 41 String userVectorFeature = personalizedRedisService.getUserVectorFeature(uid, vectorFeatureVersion);
42 if (StringUtils.isEmpty(userVectorFeature)) { 42 if (StringUtils.isEmpty(userVectorFeature)) {
43 - return null; 43 + return;
44 } 44 }
45 45
46 // 3. 传入参数调用脚本 46 // 3. 传入参数调用脚本
@@ -56,7 +56,7 @@ public class PersonalVectorFeatureSearch { @@ -56,7 +56,7 @@ public class PersonalVectorFeatureSearch {
56 scriptParams.put("factorConstant", FACTOR_CONSTANT); 56 scriptParams.put("factorConstant", FACTOR_CONSTANT);
57 logger.info("[PersonalVectorFeatureSearch.build][scriptParams={}]", scriptParams); 57 logger.info("[PersonalVectorFeatureSearch.build][scriptParams={}]", scriptParams);
58 Script script = new Script("feature_factor_vector_score", ScriptService.ScriptType.INLINE, "native", scriptParams); 58 Script script = new Script("feature_factor_vector_score", ScriptService.ScriptType.INLINE, "native", scriptParams);
59 - return ScoreFunctionBuilders.scriptFunction(script); 59 + functionScoreQueryBuilder.add(ScoreFunctionBuilders.scriptFunction(script));
60 } 60 }
61 61
62 /** 62 /**
@@ -30,6 +30,15 @@ public class SearchDynamicConfigService { @@ -30,6 +30,15 @@ public class SearchDynamicConfigService {
30 } 30 }
31 31
32 /** 32 /**
  33 + * 是否采用基于特征向量的个性化模式
  34 + *
  35 + * @return
  36 + */
  37 + public boolean openVectorFeaturePersonalized() {
  38 + return configReader.getBoolean("search.personalized.vectorfeature.open", true);
  39 + }
  40 +
  41 + /**
33 * 是否开启个性化 42 * 是否开启个性化
34 * 43 *
35 * @return 44 * @return
@@ -7,7 +7,6 @@ import org.elasticsearch.common.lucene.search.function.CombineFunction; @@ -7,7 +7,6 @@ import org.elasticsearch.common.lucene.search.function.CombineFunction;
7 import org.elasticsearch.index.query.QueryBuilder; 7 import org.elasticsearch.index.query.QueryBuilder;
8 import org.elasticsearch.index.query.QueryBuilders; 8 import org.elasticsearch.index.query.QueryBuilders;
9 import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder; 9 import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
10 -import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;  
11 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders; 10 import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
12 import org.elasticsearch.index.query.functionscore.weight.WeightBuilder; 11 import org.elasticsearch.index.query.functionscore.weight.WeightBuilder;
13 import org.springframework.beans.factory.annotation.Autowired; 12 import org.springframework.beans.factory.annotation.Autowired;
@@ -36,11 +35,12 @@ public class FunctionScoreSearchHelper { @@ -36,11 +35,12 @@ public class FunctionScoreSearchHelper {
36 public QueryBuilder buildFunctionScoreQueryBuild(QueryBuilder queryBuilder, Map<String, String> paramMap) { 35 public QueryBuilder buildFunctionScoreQueryBuild(QueryBuilder queryBuilder, Map<String, String> paramMap) {
37 FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder); 36 FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder);
38 if (searchCommonHelper.isNeedPersonalSearch(paramMap)) { 37 if (searchCommonHelper.isNeedPersonalSearch(paramMap)) {
39 - //personalizedSearch.addPersonalizedUserFetureFactor(functionScoreQueryBuilder, paramMap);  
40 - //personalizedSearch.addPersonalizedFieldValueFactor(functionScoreQueryBuilder, paramMap);  
41 - ScoreFunctionBuilder scoreFunctionBuilder = personalVectorFeatureSearch.build(paramMap.get("uid"));  
42 - if (scoreFunctionBuilder != null){  
43 - functionScoreQueryBuilder.add(scoreFunctionBuilder); 38 + if(dynamicConfig.openVectorFeaturePersonalized()) {
  39 + personalVectorFeatureSearch.addPersonalizedScriptScore(functionScoreQueryBuilder, paramMap.get("uid"));
  40 + }
  41 + else {
  42 + personalizedSearch.addPersonalizedUserFetureFactor(functionScoreQueryBuilder, paramMap);
  43 + personalizedSearch.addPersonalizedFieldValueFactor(functionScoreQueryBuilder, paramMap);
44 } 44 }
45 } 45 }
46 if (searchCommonHelper.containGlobal(paramMap)) { 46 if (searchCommonHelper.containGlobal(paramMap)) {
@@ -6,6 +6,9 @@ search.degrade.direct.downgrade=false @@ -6,6 +6,9 @@ search.degrade.direct.downgrade=false
6 #search open personalized[true:open personalized, false:close personalized] 6 #search open personalized[true:open personalized, false:close personalized]
7 search.degrade.open.personalized=true 7 search.degrade.open.personalized=true
8 8
  9 +#search open personalized based vector feature
  10 +search.personalized.vectorfeature.open=true
  11 +
9 #search open personalized[true:open personalized, false:close personalized] 12 #search open personalized[true:open personalized, false:close personalized]
10 search.degrade.personalized.maxcount=20 13 search.degrade.personalized.maxcount=20
11 14