solr入门之自定义排序之构建自己的权重计算方法及相应的排序字段

2021年9月26日 2点热度 0条评论 来源: 当以乐

需求:

1、需求:调整排序算法改为综合得分排名

2、规则:

①搜索方式:先过滤,后排序

②搜索字段:用户昵称

③匹配方式:分词完全匹配

④排序按照综合得分高低进行排序展示

综合得分=

达人得分(权重:单独计算)

+粉丝数得分(权重:75%

+基础得分(权重:25%

a.达人得分

在搜索结果中置顶展示,其中优先开通美店达人

b.粉丝数得分

粉丝数越多,权重越高(需要开发相应算法计算相对值)

c.基础得分

上传过头像、修改过签名(不重复计算)

实现思路: 设置最大权重值,每个用户按照各自条件计算相应的得分数(
最小最大规范化也叫离差标准化)
是达人时再加上最大权重(置顶效果)当达人有美店时再次加上最大权重(置顶中的置顶)
为什么可以这么做?因为要求先过滤后进行排序,既当符合搜索条件后,排序再单独进行计算
完全不需要考虑查询过程中的匹配而产生的权重.

实现:

/**
 * Copyright (C) 2015-2020 gome meixin_search Inc.All Rights Reserved.
 * 
 * FileName:UserWeightCalculator.java
 *
 * Description:简要描述本文件的内容
 *
 * History:
 * 版本号           作者                  日期               简要介绍相关操作
 *  1.0  liuyuxin  2016年4月13日
 *
 */
package cn.com.mx.gome.flash.similarity;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import cn.com.mx.gome.flash.constant.Const;
import cn.com.mx.gome.flash.entity.EcpUser;
import cn.com.mx.gome.flash.load.ConfigCenter;
import cn.com.mx.gome.flash.util.PropUtil;
import cn.com.mx.gome.search.core.weight.WeightAlgorithm;
import cn.com.mx.gome.search.core.weight.WeightCalculator;

/**
 * 
 *
 */
@Component("userWeightCalculator")
public class UserWeightCalculator implements WeightCalculator<EcpUser>, InitializingBean {

    private static final Logger logger = LoggerFactory.getLogger(UserWeightCalculator.class);

    private String defaultUserPic = null;

    /**
     * 假设的权重总分,最大粉丝数;这俩数变了,得重建索引
     */
    public Double maxUserScore = PropUtil.getInstance().getDouble(Const.WEIGHT_USER_MAX, 100000),
            maxFollowerCount = PropUtil.getInstance().getDouble(Const.WEIGHT_USER_FOLLOWER_MAX, 5000);

    /*
     * (non-Javadoc)
     * 
     * @see
     * cn.com.mx.gome.search.core.weight.WeightCalculator#calculate(java.lang
     * .Object)
     */
    @Override
    public Double calculate(EcpUser t) {
        double score = 0;
        boolean hasPic = t.getUserPic() != null
                && !(t.getUserPic().equals(defaultUserPic) && !(t.getUserPic().equalsIgnoreCase("null")));// 有头像
        boolean hasUserSign = t.getUser_sign() != null && t.getUser_sign().length() > 0
                && !(t.getUser_sign().equalsIgnoreCase("null"));// 有签名
        // 签名和头像占25%权重
        if (hasPic)
            score += (maxUserScore * 0.25) / 2;
        if (hasUserSign)
            score += (maxUserScore * 0.25) / 2;

        // 粉丝数,占75%权重
        if (t.getFollowerCount() != null && t.getFollowerCount() > 0)
            score += WeightAlgorithm.normalization(t.getFollowerCount().doubleValue(), 0.0, maxFollowerCount, 0.0,
                    maxUserScore * 0.75);

        boolean isVIP = t.getStatus() == Const.USER_STATUS_V;
        boolean hasShop = t.getType() == Const.USER_TYPE_HASSHOP;
        // 达人置顶
        if (isVIP) {
            score += maxUserScore;
            // 优先美店
            if (hasShop)
                score += maxUserScore;
        }
        t.setWeight(score);
        return score;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        defaultUserPic = configCenter.get("user.logo.default");
        logger.info("default user pic path= , {}", defaultUserPic);
    }

    @Autowired
    private ConfigCenter configCenter;
}

算法:

/**
 * Copyright (C) 2015-2020 gome meixin_search Inc.All Rights Reserved.
 * 
 * FileName:WeightAlgorithm.java
 *
 * Description:简要描述本文件的内容
 *
 * History:
 * 版本号           作者                  日期               简要介绍相关操作
 *  1.0  
 *
 */
package cn.com.mx.gome.search.core.weight;

/**
 * @author 
 *
 */
public class WeightAlgorithm {
    /**
     * 
     * @描述:最小最大规范化也叫离差标准化 ,可以对原始数据进行线性变换 ; 假定min和max是最小值和最大值,
     *                    v是该区间中的一个值,将其映射到新的区间[newMin, newMax]中为v' 则有: v' =
     *                    (v-Min)/(max-min)*(newMax-newMin)+newMin
     *                    这种方法有一个缺陷就是当有新数据加入时,可能导致max和min的变化,需要重新定义。
     * @param v
     *            做标准化的样本数据
     * @param min
     *            样本数据最小值
     * @param max
     *            样本数据最大值
     * @param newMin
     *            新的映射区间最小值
     * @param newMax
     *            新的映射区间最大值
     * @return
     * @return double
     * @exception
     * @createTime:2016年4月8日
     * @author: liuyuxin
     */
    public static Double normalization(Double v, Double min, Double max, Double newMin, Double newMax) {
        return (v - min) / (max - min) * (newMax - newMin) + newMin;
    }

}

    原文作者:当以乐
    原文地址: https://blog.csdn.net/sqh201030412/article/details/51193044
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。