七(5)查询动态-点赞评论-Redis(hash)

该博客详细介绍了社交应用中动态查询与互动的实现,包括好友动态、推荐动态的查询,以及评论、点赞和喜欢的功能。使用Redis进行数据存储和优化,通过Controller、Service和API实现各功能的交互逻辑,并提供了接口文档和代码示例。
摘要由CSDN通过智能技术生成

课程总结

1.圈子动态查询

  1. 好友动态与推荐动态

  2. 掌握动态的表关系

  3. 掌握推荐动态的流程和代码实现

2.圈子互动

  1. 使用Redis和冗余字段优化查询效率

  2. 发布评论

  3. 点赞与取消点赞

  4. 喜欢与取消喜欢

一. 动态查询

1.1 具体内容

image-20220925182120015

执行流程

image-20220925180545265

我的动态:查询个人发布的动态列表(分页查询),和之前实现的好友动态,推荐动态实现逻辑是一致。

1.2 需求分析

动态查询包含三个部分

  • 个人动态(已实现)

  • 好友动态

    • 操作用户查看所有好友发布的动态内容
  • 推荐动态

    • 探花交友平台接入大数据系统,根据个人喜欢实时计算出感兴趣的动态内容
image-20220925153754606

1.3 查询好友动态

查询好友动态与查询推荐动态显示的结构是一样的,只是其查询数据源不同

1. 接口文档

API接口文档:http://192.168.136.160:3000/project/19/interface/api/142

image-20220925153954973

2. 表结构

image-20220925154154224

3. 代码步骤
  • Controller层接受请求参数

  • Service数据封装

    • 调用API查询好友动态详情数据
    • 调用API查询动态发布人详情
    • 构造VO对象
  • API层根据用户ID查询好友发布动态详情

    • 查询好友时间线表
    • 查询动态详情
4. 代码实现
MovementController
	//查询好友动态
    @GetMapping
    public ResponseEntity movements(@RequestParam(defaultValue = "1") Integer page,
                                    @RequestParam(defaultValue = "10") Integer pagesize) {
   
        PageResult pr = movementService.findFriendMovements(page,pagesize);
        return ResponseEntity.ok(pr);
    }
MovementService
//好友动态
public PageResult findFriendMovements(Integer page, Integer pagesize) {
   
    //1、获取当前用户id
    Long userId = UserHolder.getUserId();
    //2、查询数据列表
    List<Movement> items = movementApi.findFriendMovements(userId,page,pagesize);
    //3、非空判断
    if(CollUtil.isEmpty(items)) {
   
        return new PageResult();
    }
    //4、获取好友用户id
    List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
    //5、循环数据列表
    Map<Long, UserInfo> userMaps = userInfoApi.findByIds(userIds, null);
    List<MovementsVo> vos = new ArrayList<>();
    for (Movement item : items) {
   
        //5、一个Movement构建一个Vo对象
        UserInfo userInfo = userMaps.get(item.getUserId());
        MovementsVo vo = MovementsVo.init(userInfo, item);
        vos.add(vo);
    }
    //6、构建返回值
    return new PageResult(page,pagesize,0L,vos);
}
movementApi
@Override
public List<Movement> findFriendMovements(Long friendId, Integer page, Integer pagesize) {
   
    //1、查询好友时间线表
    Query query = Query.query(Criteria.where("friendId").is(friendId))
            .skip((page - 1)*pagesize).limit(pagesize)
            .with(Sort.by(Sort.Order.desc("created")));
    List<MovementTimeLine> lines = mongoTemplate.find(query, MovementTimeLine.class);
    //2、提取动态id集合
    List<ObjectId> movementIds = CollUtil.getFieldValues(lines, "movementId", ObjectId.class);
    //3、根据动态id查询动态详情
    Query movementQuery = Query.query(Criteria.where("id").in(movementIds));
    return mongoTemplate.find(movementQuery, Movement.class);
}

1.4 查询推荐动态(redis,stream)

1. redis数据格式

推荐动态是通过推荐系统计算出的结果,现在我们只需要实现查询即可,推荐系统在后面的课程中完成。

推荐系统计算完成后,会将结果数据写入到Redis中,数据如下:

192.168.31.81:6379> get MOVEMENTS_RECOMMEND_1
"2562,3639,2063,3448,2128,2597,2893,2333,3330,2642,2541,3002,3561,3649,2384,2504,3397,2843,2341,2249"

可以看到,在Redis中的数据是有多个发布id组成(pid)由逗号分隔。所以实现中需要自己对这些数据做分页处理。

  • 推荐动态数据格式

推荐动态数据存入Redis服务器中

存入的数据KEY为MOVEMENTS_RECOMMED_{用户id}

存入的数据VALUE为:动态PID字符串(多个PID间使用“,”连接)

2. 接口文档

API接口文档:http://192.168.136.160:3000/project/19/interface/api/145

image-20220925162649789

3. 思路分析

image-20220925162757141

Redis中存储的是动态详情表的唯一数字标识 pid字段

当不存在推荐数据时,需要构造默认数据返回

4. 代码步骤
image-20220925163136829
  • Controller层接受请求参数

  • Service数据封装

    • 从redis获取当前用户的推荐PID列表
    • 如果不存在,调用API随机获取10条动态数据
    • 如果存在,调用API根据PID列表查询动态数据
    • 构造VO对象
  • API层编写方法

    • 随机获取
    • 根据pid列表查询
5. 代码实现
Constants枚举类
package com.tanhua.commons.utils;

//常量定义
public class Constants {
   

    //手机APP短信验证码CHECK_CODE_
    public static final String SMS_CODE = "CHECK_CODE_";

	//推荐动态
	public static final String MOVEMENTS_RECOMMEND = "MOVEMENTS_RECOMMEND_";

    //推荐视频
    public static final String VIDEOS_RECOMMEND = "VIDEOS_RECOMMEND_";

	//圈子互动KEY
	public static final String MOVEMENTS_INTERACT_KEY = "MOVEMENTS_INTERACT_";

    //动态点赞用户HashKey
    public static final String MOVEMENT_LIKE_HASHKEY = "MOVEMENT_LIKE_";

    //动态喜欢用户HashKey
    public static final String MOVEMENT_LOVE_HASHKEY = "MOVEMENT_LOVE_";

    //视频点赞用户HashKey
    public static final String VIDEO_LIKE_HASHKEY = "VIDEO_LIKE";

    //访问用户
    public static final String VISITORS = "VISITORS";

    //关注用户
    public static final String FOCUS_USER = "FOCUS_USER_{}_{}";

	//初始化密码
    public static final String INIT_PASSWORD = "123456";

    //环信用户前缀
    public static final String HX_USER_PREFIX = "hx";

    //jwt加密盐
    public static final String JWT_SECRET = "itcast";

    //jwt超时时间
    public static final int JWT_TIME_OUT = 3_600;
}

MovementController
/**
 * 推荐动态
 */
@GetMapping("/recommend")
public ResponseEntity recommend(@RequestParam(defaultValue = "1") Integer page,
                                @RequestParam(defaultValue = "10") Integer pagesize) {
   
    PageResult pr = movementService.findRecommendMovements(page,pagesize);
    return ResponseEntity.ok(pr);
}
MovementService
    //查询推荐动态
    public PageResult findRecommendMovements(Integer page, Integer pagesize) {
   
        //1、从redis中获取推荐数据
        String redisKey = Constants.MOVEMENTS_RECOMMEND +UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        //2、判断推荐数据是否存在
        List<Movement> list = Collections.EMPTY_LIST;
        if(StringUtils.isEmpty(redisValue)) {
   
            //3、如果不存在,调用API随机构造10条动态数据
            list = movementApi.randomMovements(pagesize);
        }else {
   
            //4、如果存在,处理pid数据   "16,17,18,19,20,21,10015,10020,10040,10064,10092,10093,10099,10067" 15
            String[] values = redisValue.split(",");
            //判断当前页的起始条数是否小于数组总数
            if
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值