Use Redis Set collection to simulate WeChat Moments. Only common friends can see the like and comment functions (SpringBoot environment)

I. Introduction

      Only common friends in WeChat Moments can see likes and comments. You can think about how to obtain common friends through a database, or query the friends of two users as a temporary table, and then compare the two Query the temporary table of user friends to obtain the common friends of two users, or query the friends of two users and extract the common friends through code. WeChat’s user friend relationships are very large, even if it is done The query pressure of sub-database and sub-table is still relatively high, and cache will definitely be used here. INNER JOIN

  • There are two directions for using cache
    • 1. Store the queried common friend information in the cache

      There is a problem with this method. Each user has many friends. For example, A has friends B and C. If the common friend information of a user and other friends is stored in the cache, then a common friend of A and B and A must be stored here. For the cache of mutual friends with C, if A has 100 or 1,000 friends, the memory required is very large, and updating is also very troublesome. This solution is not advisable.

    • 2. Store respective friend information in the cache, and then obtain the intersection (use)

      Store the users' respective friend information in the cache and use Redis Set collection storage. If you want to query the common friends of user A and user B, you only need to intersect the cache of friend information of the two users to obtain the common friends.

If you need articles on Redis’s common command set, you can view:https://blog.csdn.net/weixin_44606481/article/details/133672258

2. Use Redis Set to implement the operation of obtaining common friends

      Here, the respective friend information will be stored in the cache, and then the common friends will be obtained by intersecting. Assume that there are currently 5 usersU001、U002、U003、U004、U005, and the cache key prefix is ​​< a i=2>, user and are friends, user and are friends . FRIEND:U001U002、U003、U004U002U001、U003、U005

2.1. Add users U001 and U002 to the friend collection cache

127.0.0.1:6379> sadd FRIEND:U001 U002 U003 U004
(integer) 3
127.0.0.1:6379> sadd FRIEND:U002 U001 U003 U005
(integer) 3

2.2. Take out U001 and U002 mutual friends

127.0.0.1:6379> sinter FRIEND:U001 FRIEND:U002
1) "U003"

3. SpringBoot integrates Redis to simulate WeChat Moments so that only common friends can see the likes and comments function

If you need SpringBoot to integrate Redis, you can view the article:https://blog.csdn.net/weixin_44606481/article/details/133907103
Also Use two additional toolkits:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.74</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <optional>true</optional>
        </dependency>

3.1. Create a circle of friends entity object

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WeChatFriendCircle implements Serializable {
    
    
    /**
     * 朋友圈数据ID
     */
    private Integer id;
    /**
     * 用户编号
     */
    private String uid;
    /**
     * 朋友圈内容
     */
    private String content;
    /**
     * 创建时间
     */
    private Long createTime;
}

3.2. Implementation of core logic of circle of friends

import com.redisscene.entity.WeChatFriendCircle;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WeChatFriendCircleService {
    
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    // 朋友圈 朋友信息缓存key
    private String friendCahceKey = "FRIEND_CIRCLE:FRIEND:";
    // 朋友圈 点赞信息缓存key
    private String likeCahceKey = "FRIEND_CIRCLE:LIKE:";
    // 朋友圈 评论信息缓存key
    private String commentCahceKey = "FRIEND_CIRCLE:COMMENT:";

    // 朋友圈数据  这里不引入数据库,直接在内存中模拟
    private static List<WeChatFriendCircle> friendCircleList = new ArrayList();

    /**
     * 初始化朋友圈和好友关联信息
     */
    public void initData() {
    
    
        // 1、初始化朋友圈信息
        long timeMillis = 1701187220000L;
        WeChatFriendCircle weChatFriendCircle1 = WeChatFriendCircle.builder().id(1).uid("U001").content("PHP是世界上最好的语言!").createTime(timeMillis + 1).build();
        WeChatFriendCircle weChatFriendCircle2 = WeChatFriendCircle.builder().id(2).uid("U002").content("Python是世界上最好的语言!").createTime(timeMillis + 2).build();
        WeChatFriendCircle weChatFriendCircle3 = WeChatFriendCircle.builder().id(3).uid("U004").content("C++是世界上最好的语言!").createTime(timeMillis + 3).build();
        friendCircleList.add(weChatFriendCircle1);
        friendCircleList.add(weChatFriendCircle2);
        friendCircleList.add(weChatFriendCircle3);
        // 2、初始化点赞
        // 设置U003、U004都给朋友圈id为1的数据点赞
        redisTemplate.delete(likeCahceKey + weChatFriendCircle1.getId());
        redisTemplate.opsForSet().add(likeCahceKey + weChatFriendCircle1.getId(), "U003", "U004");

        // 3、初始化评论信息 评论信息使用hash结构存储,缓存key使用前缀加上朋友圈ID
        // 设置U003、U005都给朋友圈id为2的数据评论 这里为了方便多条评论用-_-分割
        redisTemplate.delete(commentCahceKey + weChatFriendCircle2.getId());
        redisTemplate.opsForHash().put(commentCahceKey + weChatFriendCircle2.getId(), "U003", "uid=U003 content=啊 对对对 time=1701187220009-_-uid=U003 content=你说的都对 time=1701187220005");
        redisTemplate.opsForHash().put(commentCahceKey + weChatFriendCircle2.getId(), "U005", "uid=U005 content=英雄所见略同 time=1701187220001");

        // 4、初始化用户好友关联信息
        // 给U001添加好友U002 U003 U004 这里需要把自己也加进来
        redisTemplate.delete(friendCahceKey + "U001");
        redisTemplate.opsForSet().add(friendCahceKey + "U001", "U001","U002", "U003", "U004");
        // 给U002添加好友U001 U003 U005 这里需要把自己也加进来
        redisTemplate.delete(friendCahceKey + "U002");
        redisTemplate.opsForSet().add(friendCahceKey + "U002", "U001","U002", "U003", "U005");
    }


    /**
     * 查看朋友圈列表
     * @param uid 用户ID
     */
    public List queryFriendCircleList(String uid) {
    
    
        // 1、查询用户好友列表
        Set<String> friends = redisTemplate.opsForSet().members(friendCahceKey + uid);
        friends.add(uid); // 将自己也加入到好友列表中 因为也需要查询自己发送的朋友圈数据

        // 2、查询用户能看到的朋友圈列表
        List<Map> resultList = new ArrayList<>();
        for (WeChatFriendCircle weChatFriendCircle : friendCircleList) {
    
    
            if(friends.contains(weChatFriendCircle.getUid())) {
    
    
                // 3、获取用户和当前朋友圈用户的共同好友信息
                Set<String> commonFriends = redisTemplate.opsForSet().intersect(friendCahceKey + uid, friendCahceKey + weChatFriendCircle.getUid());

                // 4、查询当前朋友圈共同好友点赞列表 取共同好友列表与点赞列表的交集
                Set<String> likes = redisTemplate.opsForSet().intersect(likeCahceKey + weChatFriendCircle.getId(),friendCahceKey + uid);

                // 5、查询当前朋友圈共同好友评论信息列表
                HashOperations<String, String, String> hashOperations = redisTemplate.opsForHash();
                List<String> comments = hashOperations.multiGet(commentCahceKey + weChatFriendCircle.getId(), commonFriends);

                // 组装数据
                Map dataMap = new HashMap();
                dataMap.put("id", weChatFriendCircle.getId());
                dataMap.put("uid", weChatFriendCircle.getUid());
                dataMap.put("content", weChatFriendCircle.getContent());
                dataMap.put("createTime", weChatFriendCircle.getCreateTime());
                dataMap.put("likes", likes);
                dataMap.put("comments", comments.stream().filter(item->item!=null).collect(Collectors.toList()));
                resultList.add(dataMap);
            }
        }
        return resultList;
    }
}

3.3. Moments query test

import com.alibaba.fastjson.JSON;
import com.redisscene.service.WeChatFriendCircleService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class WeChatFriendCircleTest {
    
    
    @Autowired
    private WeChatFriendCircleService weChatFriendCircleService;

    @Test
    public void t1(){
    
    
        // 初始化数据
        weChatFriendCircleService.initData();
        // 查询用户U001的朋友圈
        List list = weChatFriendCircleService.queryFriendCircleList("U001");
        System.out.println(JSON.toJSONString(list));
        // 查询用户U002的朋友圈
		List list2 = weChatFriendCircleService.queryFriendCircleList("U002");
        System.out.println(JSON.toJSONString(list2));
    }
}

The data obtained after runningU001 is:

[
    {
    
    
        "uid":"U001",
        "comments":[

        ],
        "createTime":1701187220001,
        "id":1,
        "content":"PHP是世界上最好的语言!",
        "likes":[
            "U003",
            "U004"
        ]
    },
    {
    
    
        "uid":"U002",
        "comments":[
            "uid=U003 content=啊 对对对 time=1701187220009-_-uid=U003 content=你说的都对 time=1701187220005"
        ],
        "createTime":1701187220002,
        "id":2,
        "content":"Python是世界上最好的语言!",
        "likes":[

        ]
    },
    {
    
    
        "uid":"U004",
        "comments":[

        ],
        "createTime":1701187220003,
        "id":3,
        "content":"C++是世界上最好的语言!",
        "likes":[

        ]
    }
]

The data obtained after runningU002 is:

[
    {
    
    
        "uid":"U001",
        "comments":[

        ],
        "createTime":1701187220001,
        "id":1,
        "content":"PHP是世界上最好的语言!",
        "likes":[
            "U003"
        ]
    },
    {
    
    
        "uid":"U002",
        "comments":[
            "uid=U003 content=啊 对对对 time=1701187220009-_-uid=U003 content=你说的都对 time=1701187220005",
            "uid=U005 content=英雄所见略同 time=1701187220001"
        ],
        "createTime":1701187220002,
        "id":2,
        "content":"Python是世界上最好的语言!",
        "likes":[

        ]
    }
]

Guess you like

Origin blog.csdn.net/weixin_44606481/article/details/134468761