Redis——friends follow, common follow, Feed stream push

1. Friends follow

On the details page of the store's pictures and texts, you can follow the author who released the notes:

Entering the note details page of Tandian, two requests will be issued , one is to judge whether you have followed the user, and the other is to try to follow the user's request.

 

Follow is the relationship between users , the relationship between bloggers and fans. There is a tb_follow table in the database to indicate:

Where userId is the currently logged in user id, follow_user_id is the followed user id

Implement the corresponding interface:

1. Determine whether to pay attention to:

Controller layer:

@GetMapping("/or/not/{id}")
public Result isFollow(@PathVariable("id") Long followUserId) {
      return followService.isFollow(followUserId);
}

Service layer:

@Override
public Result isFollow(Long followUserId) {
        // 1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        // 2.查询是否关注 select count(*) from tb_follow where user_id = ? and follow_user_id = ?
        Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();
        // 3.判断
        return Result.ok(count > 0);
    }

2. Follow the business interface: If you have already followed, add data such as userid (the id of the currently logged in user) and the followed user id (follow_user_id) to the database.

If not concerned, delete the data.

Controller layer:

//关注
@PutMapping("/{id}/{isFollow}")
public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFollow) {
    return followService.follow(followUserId, isFollow);
}

Service layer:

关注service
 @Override
    public Result follow(Long followUserId, Boolean isFollow) {
        // 1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        // 1.判断到底是关注还是取关
        if (isFollow) {
            // 2.关注,新增数据
            Follow follow = new Follow();
            follow.setUserId(userId);
            follow.setFollowUserId(followUserId);
            boolean isSuccess = save(follow);

        } else {
            // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
            remove(new QueryWrapper<Follow>()
                    .eq("user_id", userId).eq("follow_user_id", followUserId));

        }
        return Result.ok();
    }

 2. Shared attention of friends

 Requirement: Use the appropriate data structure in Redis to realize the common attention function. The blogger's personal page shows the common concerns of current users and bloggers.

We can use the set collection in Redis to store the user id that each user follows, that is, follow_user_id, into the set collection. Each user corresponds to a set collection that follows bloggers, and then take the intersection between them . Find fellow bloggers to follow.

Therefore, we need to transform the business logic of following users first, and store the following users in the Set collection every time a user pays attention.

 Focus on business transformation:

@Override
public Result follow(Long followUserId, Boolean isFollow) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();
    String key = "follows:" + userId;
    // 1.判断到底是关注还是取关
    if (isFollow) {
        // 2.关注,新增数据
        Follow follow = new Follow();
        follow.setUserId(userId);
        follow.setFollowUserId(followUserId);
        boolean isSuccess = save(follow);
        if (isSuccess) {
            // 把关注用户的id,放入redis的set集合 sadd userId followerUserId
            stringRedisTemplate.opsForSet().add(key, followUserId.toString());
        }
    } else {
        // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
        boolean isSuccess = remove(new QueryWrapper<Follow>()
                .eq("user_id", userId).eq("follow_user_id", followUserId));
        if (isSuccess) {
            // 把关注用户的id从Redis集合中移除
            stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
        }
    }
    return Result.ok();
}

Then, we can implement the common concern interface.

 

  Controller layer:

@GetMapping("/common/{id}")
    public Result followCommons(@PathVariable("id") Long followUserId){
        return followService.followCommons(followUserId);
    }

Service layer:

1. Obtain the key of the current user id and target user id in redis

2. Use the method of intersection in set to get the result

3. Parse the result and get the id combination

4. Obtain user combination through id combination.

5. Return the user combination to the front end.

@Override
public Result followCommons(Long id) {
    // 1.获取当前用户
    Long userId = UserHolder.getUser().getId();
    String key = "follows:" + userId;
    // 2.求交集
    String key2 = "follows:" + id;
    Set<String> intersect = stringRedisTemplate.opsForSet().intersect(key, key2);
    if (intersect == null || intersect.isEmpty()) {
        // 无交集
        return Result.ok(Collections.emptyList());
    }
    // 3.解析id集合
    List<Long> ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());
    // 4.查询用户
    List<UserDTO> users = userService.listByIds(ids)
            .stream()
            .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
            .collect(Collectors.toList());
    return Result.ok(users);
}

Common focus on function implementation.

3. Pay attention to push (feed flow) 

Follow push is also called Feed flow, literally translated as feeding . Continuously provide users with an "immersive" experience, and obtain new information through infinite pull-down refresh.

The traditional push mode is that the user searches for the content by himself, but Feed fetches and finds the corresponding user based on the content information and pushes it

 

There are two common patterns for feed stream products:

Timeline : No content screening, simply sorted by content release time, often used for friends or followers. For example circle of friends

  • Advantages: comprehensive information, there will be no missing. And it is relatively simple to implement

  • Disadvantages: There is a lot of information noise, users may not be interested, and the efficiency of content acquisition is low

Intelligent sorting : Use intelligent algorithms to block out content that violates regulations and is not of interest to users. Push information that users are interested in to attract users

  • Advantages: Feed the information that users are interested in, the user viscosity is very high, and it is easy to become addicted

  • Disadvantage: If the algorithm is not accurate, it may be counterproductive

 

Here we focus on the push, we use the first type of  Timeline.

There are also three ways to implement this mode:

1. Pull mode

Also known as read diffusion. It means that each blogger has an outbox after sending blog information. At this time, fans want to read their information, they pull the information from this outbox to their own inbox and read it . So it is called pull mode.

 Cons: There may be a delay

2. Push mode

Also known as write diffusion. After a blogger publishes blog information, it directly pushes the blog to the inbox of fans . This method solves the latency problem of pull mode, but it also causes memory problems.

 

3. Push-pull combination

Also known as read-write mixing, it has the advantages of both push and pull modes.

Now there are three fans who follow the big V blogger at the same time, and two fans follow the ordinary blogger Zhang San. 

At this time, Zhang San sent blog information, but since he is an ordinary blogger with a small fan base, he does not need to worry about memory problems, so he directly uses the push mode to send it to fans.

 For big V bloggers, fans are divided into active fans and ordinary fans. Active fans use the push mode, while ordinary fans use the pull mode to put messages into the inbox.

These are the three implementation modes, let's make a comparison. 

 

Here, we use the push mode to implement the friend push function.

Here is a pagination question:

The data in the feed stream will be updated continuously, so the subtitles of the data will also change, so the traditional pagination mode cannot be used . 

Traditional paging mode:

Therefore, we must adopt the scrolling pagination of the feed stream .

1. First, revise the business of adding shop-exploring notes, and push them to fans’ inboxes while saving the blog to the database

    @Override
    public Result saveBlog(Blog blog) {
        // 获取登录用户
        UserDTO user = UserHolder.getUser();
        blog.setUserId(user.getId());
        // 保存探店博文
        boolean isSuccess = save(blog);
        if (!isSuccess){
            //没有保存成功,返回错误信息
            return Result.fail("新增失败!");
        }
        //成功,将博客信息放到粉丝收件箱
        //1.先获取粉丝群体 select * from tb_follow where follow_user_id = ?
        QueryChainWrapper<Follow> follows = followService.query().eq("follow_user_id", user.getId());
        //2.将消息推送至粉丝收件箱
        String key = "feeds:"+user.getId();
        stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis());
        // 返回id
        return Result.ok(blog.getId());
    }

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_59212867/article/details/128347694