Authored by 胡古飞

修改用户特征的打分方式

... ... @@ -10,8 +10,9 @@ import org.elasticsearch.common.lucene.search.function.FieldValueFactorFunction;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilder;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.index.query.functionscore.fieldvaluefactor.FieldValueFactorFunctionBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -146,7 +147,7 @@ public final class PersonalizedSearch {
if (isFuzzySearch) {
boost = getAdaptoredBoost(maxBoost, boost);
}
if(boost<0){
if (boost < 0) {
boost = 0;
}
boolQueryBuilder.should(QueryBuilders.termQuery(searchFeature.getTargetParam(), searchFeature.getParamValues()).boost(boost));
... ... @@ -154,14 +155,56 @@ public final class PersonalizedSearch {
return boolQueryBuilder;
}
public ScoreFunctionBuilder getPersonalizedScoreFunctionBuilder(Map<String, String> paramMap) {
public void addPersonalizedFieldValueFactor(FunctionScoreQueryBuilder functionScoreQueryBuilder, Map<String, String> paramMap) {
String pageId = this.getPageIdFromParamMap(paramMap);
float factor = getFunctionScoreFactor(pageId);
String fieldName = getFuncScoreField(pageId);
return ScoreFunctionBuilders.fieldValueFactorFunction(fieldName).factor(factor).modifier(FieldValueFactorFunction.Modifier.LOG2P)
.missing(PConsts.PRODUCT_FUNCTION_MISSING_VALUE);
FieldValueFactorFunctionBuilder fieldValueFactorFunctionBuilder = ScoreFunctionBuilders.fieldValueFactorFunction(fieldName).factor(factor)
.modifier(FieldValueFactorFunction.Modifier.LOG2P).missing(PConsts.PRODUCT_FUNCTION_MISSING_VALUE);
functionScoreQueryBuilder.add(fieldValueFactorFunctionBuilder);
}
public void addPersonalizedUserFetureFactor(FunctionScoreQueryBuilder functionScoreQueryBuilder, Map<String, String> paramMap) {
// 1、获取用户信息和页面信息
String uid = this.getUidFromParamMap(paramMap);
String pageId = this.getPageIdFromParamMap(paramMap);
List<SearchFeature> sfRedis = userFeatures.getUserFeaturesFromRedis(uid, pageId);
if (sfRedis == null || sfRedis.isEmpty()) {
return;
}
// 2、对 用户权重进行排序,should个数超过一定数量, 按权重值desc排序, 截取数据
List<SearchFeature> searchFeatures = null;
if (sfRedis.size() > ISearchConstants.PERSONALIZED_SEARCH_SHOULD_MAX) {
// 按照boost进行排序
Collections.sort(sfRedis, new Comparator<SearchFeature>() {
@Override
public int compare(SearchFeature left, SearchFeature right) {
Float fleft = Float.valueOf(left.getBoost());
Float fright = Float.valueOf(right.getBoost());
return fright.compareTo(fleft);
}
});
searchFeatures = sfRedis.subList(0, ISearchConstants.PERSONALIZED_SEARCH_SHOULD_MAX);
} else {
searchFeatures = sfRedis;
}
// 3、对用户权重 进行加分[以乘的方式]
float maxBoost = this.getMaxBoost(searchFeatures);// 获取用户最大的boost,已调整boost值
boolean isFuzzySearch = this.isFuzzySearch(pageId);
for (SearchFeature searchFeature : searchFeatures) {
float boost = searchFeature.getBoost();
if (boost < 0) {
boost = 0;
}
float weight = 1 + boost / (maxBoost);// 非模糊查询时,用户特征最大加分值为2
if (isFuzzySearch) {
weight = 1 + boost / (maxBoost * 10);// 模糊查询时,用户特征最大加分值为1.1
}
functionScoreQueryBuilder.add(QueryBuilders.termQuery(searchFeature.getTargetParam(), searchFeature.getParamValues()),
ScoreFunctionBuilders.weightFactorFunction(weight));
}
}
private float getMaxBoost(List<SearchFeature> searchFeatures) {
float boost = 0f;
for (SearchFeature searchFeature : searchFeatures) {
... ...
... ... @@ -24,29 +24,33 @@ public class FunctionScoreSearchHelper {
@Autowired
private SearchDynamicConfigService dynamicConfig;
private static float globalWeight = 0.50f;
//private static float brandTotalMatchWeight = 5f;
static float globalWeight = 0.50f;
static float brandTotalMatchWeight = 3f;
private WeightBuilder genWeightFactorBuilder(float factor) {
return ScoreFunctionBuilders.weightFactorFunction(factor);
}
public QueryBuilder buildFunctionScoreQueryBuild(QueryBuilder queryBuilder, Map<String, String> paramMap) {
// 个性化时先对用户特征加分
if (searchCommonHelper.isNeedPersonalSearch(paramMap)) {
queryBuilder = personalizedSearch.buildPersonalizedQueryBuilder(queryBuilder, paramMap);
}
// // 个性化时先对用户特征加分
// if (searchCommonHelper.isNeedPersonalSearch(paramMap)) {
// queryBuilder =
// personalizedSearch.buildPersonalizedQueryBuilder(queryBuilder,
// paramMap);
// }
FunctionScoreQueryBuilder functionScoreQueryBuilder = new FunctionScoreQueryBuilder(queryBuilder);
if (searchCommonHelper.isNeedPersonalSearch(paramMap)) {
functionScoreQueryBuilder.add(personalizedSearch.getPersonalizedScoreFunctionBuilder(paramMap));
personalizedSearch.addPersonalizedUserFetureFactor(functionScoreQueryBuilder, paramMap);
personalizedSearch.addPersonalizedFieldValueFactor(functionScoreQueryBuilder, paramMap);
}
if (searchCommonHelper.containGlobal(paramMap)) {
functionScoreQueryBuilder.add(QueryBuilders.termQuery("isGlobal", "Y"), genWeightFactorBuilder(globalWeight));
}
// if (searchCommonHelper.isFuzzySearchDefault(paramMap)) {
// String queryLowerCase = paramMap.get("query").trim().toLowerCase();
// functionScoreQueryBuilder.add(QueryBuilders.termQuery("brandName.brandName_lowercase", queryLowerCase), this.genWeightFactorBuilder(brandTotalMatchWeight));
// }
// if (searchCommonHelper.isFuzzySearchDefault(paramMap)) {
// String queryLowerCase = paramMap.get("query").trim().toLowerCase();
// functionScoreQueryBuilder.add(QueryBuilders.termQuery("brandName.brandName_lowercase",
// queryLowerCase), this.genWeightFactorBuilder(brandTotalMatchWeight));
// }
if (searchCommonHelper.isNeedDeScoreBrandSearch(paramMap)) {
functionScoreQueryBuilder.add(QueryBuilders.termQuery("isForbiddenSortBrand", "1"), ScoreFunctionBuilders.weightFactorFunction(0));
}
... ...
... ... @@ -30,7 +30,7 @@ search.index.translog.flush_threshold_ops=5000
#search
search.minimum.should.match=75%
search.operator=and
search.default.field=brandName.brandName_lowercase^2000,smallSort^1000,smallSort.smallSort_pinyin^1000,middleSort^950,middleSort.middleSort_pinyin^950,maxSort^900,maxSort.maxSort_pinyin^900,brandName^900,brandNameCn^850,brandNameCn.brandNameCn_pinyin^850,brandNameEn^800,brandDomain^800,specialSearchField^700,productName.productName_ansj^300,standardOnlyNames.standardOnlyNames_pinyin^250,standardOnlyNames.standardOnlyNames_ansj^250,productKeyword^50,brandKeyword^30,genderS^20,searchField_ansj^10,searchField,productSkn.productSkn_ansj
search.default.field=brandName.brandName_lowercase^2500,smallSort^1000,smallSort.smallSort_pinyin^1000,middleSort^950,middleSort.middleSort_pinyin^950,maxSort^900,maxSort.maxSort_pinyin^900,brandName^900,brandNameCn^850,brandNameCn.brandNameCn_pinyin^850,brandNameEn^800,brandDomain^800,specialSearchField^700,productName.productName_ansj^300,standardOnlyNames.standardOnlyNames_pinyin^250,standardOnlyNames.standardOnlyNames_ansj^250,productKeyword^50,brandKeyword^30,genderS^20,searchField_ansj^10,searchField,productSkn.productSkn_ansj
search.script.score=_score+doc['sortWeight'].value*0.003+(100-doc['breakingRate'].value)/100 * doc['salesWithDateDiff'].value/pow((now-doc['shelveTime'].value)/3600+2,1.8)
search.script.lang=groovy
... ...
... ... @@ -30,7 +30,7 @@ search.index.translog.flush_threshold_ops=${search.index.translog.flush_threshol
#search
search.minimum.should.match=75%
search.operator=and
search.default.field=brandName.brandName_lowercase^2000,smallSort^1000,smallSort.smallSort_pinyin^1000,middleSort^950,middleSort.middleSort_pinyin^950,maxSort^900,maxSort.maxSort_pinyin^900,brandName^900,brandNameCn^850,brandNameCn.brandNameCn_pinyin^850,brandNameEn^800,brandDomain^800,specialSearchField^700,productName.productName_ansj^300,standardOnlyNames.standardOnlyNames_pinyin^250,standardOnlyNames.standardOnlyNames_ansj^250,productKeyword^50,brandKeyword^30,genderS^20,searchField_ansj^10,searchField,productSkn.productSkn_ansj
search.default.field=brandName.brandName_lowercase^2500,smallSort^1000,smallSort.smallSort_pinyin^1000,middleSort^950,middleSort.middleSort_pinyin^950,maxSort^900,maxSort.maxSort_pinyin^900,brandName^900,brandNameCn^850,brandNameCn.brandNameCn_pinyin^850,brandNameEn^800,brandDomain^800,specialSearchField^700,productName.productName_ansj^300,standardOnlyNames.standardOnlyNames_pinyin^250,standardOnlyNames.standardOnlyNames_ansj^250,productKeyword^50,brandKeyword^30,genderS^20,searchField_ansj^10,searchField,productSkn.productSkn_ansj
search.script.score=_score+doc['sortWeight'].value*0.003+(100-doc['breakingRate'].value)/100 * doc['salesWithDateDiff'].value/pow((now-doc['shelveTime'].value)/3600+2,1.8)
search.script.lang=groovy
... ...