redis+springboot实现TOP10排行榜

一、控制层

package com.citydo.xclouddesk.webapi.knowledgebase;



import com.citydo.xclouddesk.knowledgebase.service.HotMessageService;
import com.citydo.xclouddesk.utils.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author nick
 */
@RestController
@RequestMapping("/ikbs/v1/hop-message/tenants/{tenantId}/hot-ten")
@Slf4j
public class HotMessageController {


    @Resource
    private HotMessageService hotMessageService;

    /**
     * 添加数据
     */
    @PostMapping
    public CommonResponse<String> redisAdd(@PathVariable("tenantId") String tenantId,
                                           @RequestParam(required = false) String message) {
        hotMessageService.addTop(message,tenantId);
        return CommonResponse.success();
    }

    /**
     * 根据key搜索相关最热的前十名
     */
    @GetMapping
    public CommonResponse<List<String>> redisGet(@PathVariable("tenantId") String tenantId) {
        Map<String, Object> params = new HashMap<>(1);
        params.put("tenantId",tenantId);
        return CommonResponse.success(hotMessageService.getTopList(params));
    }

    /**
     * 热点问题计数
     */
    @PutMapping
    public CommonResponse<String> incrementScore(@PathVariable("tenantId") String tenantId,
                                                 @RequestBody Map<String, Object> params) {
        params.put("tenantId",tenantId);
        hotMessageService.incrementScore(params);
        return CommonResponse.success();
    }
}

二、接口层

package com.citydo.xclouddesk.knowledgebase.service;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;

/**
 * @author nick
 */
@Service
@Slf4j
public class HotMessageService {

    @Resource
    private RedisTemplate redisTemplate;

    /**
     * 添加数据 通过租户ID进行区分
     * @param message 回答问题
     * @param tenantId 租户ID
     */
    public void addTop(String message, String tenantId){
        //预处理数据
        if (StringUtils.isNotBlank(message)) {
            //去除标点等特殊词
            String author = message.replaceAll("\\﹝.*?\\﹞|\\〔.*?\\〕|\\(.*?\\)|\\{.*?}|\\[.*?]|\\[.*?]|\\【.*?】|(.*?)|等|著|编者|主编|[^0-9a-zA-Z\u4e00-\u9fa5.,,•·《 》]", "").trim();
            message = author.replaceAll("\\s+", " ").trim();
            //去除html标签
            Jsoup.clean(message, Whitelist.none());
            //用租户ID进行 添加到redis数据中
            Long now = System.currentTimeMillis();
            ZSetOperations zSetOperations = redisTemplate.opsForZSet();
            ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
            //转list类型
            List<String> title = Arrays.asList(message);
            for (int i = 0, lends = title.size(); i < lends; i++) {
                String tle = title.get(i);
                try {
                    if (zSetOperations.score(tenantId, tle) <= 0) {
                        zSetOperations.add(tenantId, tle, 0);
                        valueOperations.set(tle, now);
                    }
                } catch (Exception e) {
                    zSetOperations.add(tenantId, tle, 0);
                    valueOperations.set(tle, now);
                }
            }
        }
    }


    /**
     *根据key搜索相关最热的前十名
     * tenantId 标识租户ID
     * key 表示内容
     */
    public List<String> getTopList(Map<String, Object> params){
        //String key = params.get("key").toString();
        String vacs = params.get("tenantId").toString();
        Long now = System.currentTimeMillis();
        List<String> result = new ArrayList<>();
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
        Set<String> value = zSetOperations.reverseRangeByScore(vacs, 0, Double.MAX_VALUE);
        //key不为空的时候 推荐相关的最热前十名
        for (String val : value) {
            //if (StringUtils.containsIgnoreCase(val, key)) {}
                //只返回最热的前十名
                if (result.size() > 9) {
                    break;
                }
                //返回最近一个月的数据
                Long time = valueOperations.get(val);
                if ((now - time) < 2592000000L) {
                    result.add(val);
                } else {
                    //时间超过一个月没搜索就把这个词热度归0
                    zSetOperations.add(vacs, val, 0);
                }
        }
        return result;
    }

    /**
     * 每次点击给相关词热度 +1
     * @param params
     * key 标识问题
     * tenantId 标识租户ID
     */
    public void incrementScore(Map<String, Object> params){
        String key = params.get("key").toString();
        String vacs = params.get("tenantId").toString();
        Long now = System.currentTimeMillis();
        ZSetOperations zSetOperations = redisTemplate.opsForZSet();
        ValueOperations<String, Long> valueOperations = redisTemplate.opsForValue();
        zSetOperations.incrementScore(vacs, key, 1);
        valueOperations.getAndSet(key, now);
    }
}

参考:https://blog.csdn.net/wangh92/category_6969732.html

发布了226 篇原创文章 · 获赞 515 · 访问量 69万+

猜你喜欢

转载自blog.csdn.net/qq_32447301/article/details/104071071