...
|
...
|
@@ -20,69 +20,92 @@ import com.yoho.search.service.service.SearchDynamicConfigService; |
|
|
public class PersonalVectorFeatureSearch {
|
|
|
|
|
|
private static final Logger PERSONALIZED = LoggerFactory.getLogger("PERSONALIZED");
|
|
|
|
|
|
private static final Double BASE_CONSTANT = 1.0D;
|
|
|
|
|
|
private static final Double FACTOR_CONSTANT = 0.8D;
|
|
|
|
|
|
@Autowired
|
|
|
private SearchDynamicConfigService searchDynamicConfigService;
|
|
|
|
|
|
@Autowired
|
|
|
private PersonalizedRedisService personalizedRedisService;
|
|
|
|
|
|
public void addPersonalizedScriptScore(FunctionScoreQueryBuilder functionScoreQueryBuilder, Map<String, String> paramMap) {
|
|
|
private void doAddPersionalFunctionScoreQueryBuilder(FunctionScoreQueryBuilder functionScoreQueryBuilder, String userVectorFeature, String vectorFeatureVersion) {
|
|
|
Map<String, Object> scriptParams = new HashMap<>();
|
|
|
scriptParams.put("field", "productFeatureFactor");
|
|
|
scriptParams.put("userFeatureFactors", userVectorFeature);
|
|
|
scriptParams.put("vectorFeatureVersion", vectorFeatureVersion);
|
|
|
scriptParams.put("baseConstant", BASE_CONSTANT);
|
|
|
scriptParams.put("factorConstant", FACTOR_CONSTANT);
|
|
|
Script script = new Script("feature_factor_vector_score", ScriptService.ScriptType.INLINE, "native", scriptParams);
|
|
|
functionScoreQueryBuilder.add(ScoreFunctionBuilders.scriptFunction(script));
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 通用的个性化打分逻辑
|
|
|
*
|
|
|
* @param functionScoreQueryBuilder
|
|
|
* @param paramMap
|
|
|
*/
|
|
|
public void addCommonPersonalizedScriptScore(FunctionScoreQueryBuilder functionScoreQueryBuilder, Map<String, String> paramMap) {
|
|
|
// 1. 获取特征向量版本(即生成时间,该时间需要与skn的生成时间一致才有意义)
|
|
|
String vectorFeatureVersion = searchDynamicConfigService.personalizedSearchVersion();
|
|
|
if (StringUtils.isEmpty(vectorFeatureVersion) || "-1".equals(vectorFeatureVersion)) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
String uid = paramMap.get("uid");
|
|
|
|
|
|
// 2. 获取用户的特征向量
|
|
|
String userVectorFeature = personalizedRedisService.getUserVectorFeature(uid, vectorFeatureVersion);
|
|
|
if (StringUtils.isEmpty(userVectorFeature)) {
|
|
|
return;
|
|
|
}
|
|
|
PERSONALIZED.info("do common personal search , paramString is [{}]", HttpServletRequestUtils.genParamString(paramMap));
|
|
|
// 3、添加个性化打分脚本
|
|
|
this.doAddPersionalFunctionScoreQueryBuilder(functionScoreQueryBuilder, userVectorFeature, vectorFeatureVersion);
|
|
|
}
|
|
|
|
|
|
PERSONALIZED.info("do personal search , paramString is [{}]", HttpServletRequestUtils.genParamString(paramMap));
|
|
|
|
|
|
// 3. 传入参数调用脚本
|
|
|
// field -> productindex索引种保存skn特征向量的字段名
|
|
|
// userFeatureFactors -> 用户特征向量值,多个值之间用逗号分隔
|
|
|
// vectorFeatureVersion -> 用户特征向量版本,当与skn的版本一致才计算相关性
|
|
|
// baseConstant,factorConstant -> 相关性常量和系数,计算规则为 baseConstant +
|
|
|
// factorConstant * cos(Vuser, Vskn)
|
|
|
Map<String, Object> scriptParams = new HashMap<>();
|
|
|
scriptParams.put("field", "productFeatureFactor");
|
|
|
scriptParams.put("userFeatureFactors", userVectorFeature);
|
|
|
scriptParams.put("vectorFeatureVersion", vectorFeatureVersion);
|
|
|
scriptParams.put("baseConstant", BASE_CONSTANT);
|
|
|
scriptParams.put("factorConstant", FACTOR_CONSTANT);
|
|
|
Script script = new Script("feature_factor_vector_score", ScriptService.ScriptType.INLINE, "native", scriptParams);
|
|
|
functionScoreQueryBuilder.add(ScoreFunctionBuilders.scriptFunction(script));
|
|
|
/**
|
|
|
* 活动个性化打分逻辑【使用用户购物车、收藏夹的维度】
|
|
|
*
|
|
|
* @param functionScoreQueryBuilder
|
|
|
* @param paramMap
|
|
|
*/
|
|
|
public void addActivityPersonalizedScriptScore(FunctionScoreQueryBuilder functionScoreQueryBuilder, Map<String, String> paramMap) {
|
|
|
// 1. 获取特征向量版本(即生成时间,该时间需要与skn的生成时间一致才有意义)
|
|
|
String vectorFeatureVersion = searchDynamicConfigService.personalizedSearchVersion();
|
|
|
if (StringUtils.isEmpty(vectorFeatureVersion) || "-1".equals(vectorFeatureVersion)) {
|
|
|
return;
|
|
|
}
|
|
|
String uid = paramMap.get("uid");
|
|
|
// 2. 获取用户的特征向量
|
|
|
String userVectorFeature = personalizedRedisService.getUserActivityVectorFeature(uid, vectorFeatureVersion);
|
|
|
if (StringUtils.isEmpty(userVectorFeature)) {
|
|
|
userVectorFeature = personalizedRedisService.getUserVectorFeature(uid, vectorFeatureVersion);
|
|
|
}
|
|
|
if (StringUtils.isEmpty(userVectorFeature)) {
|
|
|
return;
|
|
|
}
|
|
|
PERSONALIZED.info("do activity personal search , paramString is [{}]", HttpServletRequestUtils.genParamString(paramMap));
|
|
|
// 3、添加个性化打分脚本
|
|
|
this.doAddPersionalFunctionScoreQueryBuilder(functionScoreQueryBuilder, userVectorFeature, vectorFeatureVersion);
|
|
|
}
|
|
|
|
|
|
public void addPersonalizedScriptScoreUserProductFeature(FunctionScoreQueryBuilder functionScoreQueryBuilder, String productVectorFeature) {
|
|
|
/**
|
|
|
* 直接使用商品特征的个性化打分逻辑
|
|
|
*
|
|
|
* @param functionScoreQueryBuilder
|
|
|
* @param paramMap
|
|
|
*/
|
|
|
public void addProductPersonalizedScriptScore(FunctionScoreQueryBuilder functionScoreQueryBuilder, String productVectorFeature) {
|
|
|
// 1. 获取商品特征向量
|
|
|
if(StringUtils.isBlank(productVectorFeature)){
|
|
|
if (StringUtils.isBlank(productVectorFeature)) {
|
|
|
return;
|
|
|
}
|
|
|
// 2. 传入参数调用脚本,以商品特征代替用户特征
|
|
|
Map<String, Object> scriptParams = new HashMap<>();
|
|
|
scriptParams.put("field", "productFeatureFactor");
|
|
|
|
|
|
String [] productVectorFeatures = productVectorFeature.split("\\|",2);
|
|
|
if(productVectorFeatures.length!=2){
|
|
|
String[] productVectorFeatures = productVectorFeature.split("\\|", 2);
|
|
|
if (productVectorFeatures.length != 2) {
|
|
|
return;
|
|
|
}
|
|
|
scriptParams.put("userFeatureFactors", productVectorFeatures[1]);
|
|
|
scriptParams.put("vectorFeatureVersion", productVectorFeatures[0]);
|
|
|
scriptParams.put("baseConstant", BASE_CONSTANT);
|
|
|
scriptParams.put("factorConstant", FACTOR_CONSTANT);
|
|
|
Script script = new Script("feature_factor_vector_score", ScriptService.ScriptType.INLINE, "native", scriptParams);
|
|
|
functionScoreQueryBuilder.add(ScoreFunctionBuilders.scriptFunction(script));
|
|
|
// 3、添加个性化打分脚本
|
|
|
this.doAddPersionalFunctionScoreQueryBuilder(functionScoreQueryBuilder, productVectorFeatures[1], productVectorFeatures[0]);
|
|
|
}
|
|
|
|
|
|
/**
|
...
|
...
|
|