6

使用 Redis 储存社交关系 — blog.huangz.me

 3 years ago
source link: https://blog.huangz.me/2019/redis-sns-relationship.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用 Redis 储存社交关系

本文摘录自即将出版的《Redis使用手册》, 详情请见: RedisGuide.com

微博、twitter 以及类似的社交网站都允许用户通过加关注或者加好友的方式, 构建一种社交关系: 这些网站上的每个用户都可以关注其他用户, 也可以被其他用户关注。 通过正在关注名单(following list), 用户可以查看自己正在关注的用户及其人数; 而通过关注者名单(follower llist), 用户可以查看有哪些人正在关注自己, 以及有多少人正在关注自己。

代码清单 5-5 展示了一个使用集合来记录社交关系的方法:

  • 程序为每个用户维持两个集合, 一个集合储存用户的正在关注名单, 而另一个集合则储存用户的关注者名单。

  • 当一个用户(关注者)关注另一个用户(被关注者)的时候, 程序会将被关注者添加到关注者的正在关注名单里面, 并将关注者添加到被关注者的关注者名单里面。

  • 当关注者取消对被关注者的关注时, 程序会将被关注者从关注者的正在关注名单中移除, 并将关注者从被关注者的关注者名单中移除。


代码清单 5-5 使用集合实现社交关系:/set/relationship.py

def following_key(user):
    return user + "::following"

def follower_key(user):
    return user + "::follower"

class Relationship:

    def __init__(self, client, user):
        self.client = client
        self.user = user

    def follow(self, target):
        """
        关注目标用户。
        """
        # 把 target 添加到当前用户的正在关注集合里面
        user_following_set = following_key(self.user)
        self.client.sadd(user_following_set, target)
        # 把当前用户添加到 target 的关注者集合里面
        target_follower_set = follower_key(target)
        self.client.sadd(target_follower_set, self.user)

    def unfollow(self, target):
        """
        取消对目标用户的关注。
        """
        # 从当前用户的正在关注集合中移除 target
        user_following_set = following_key(self.user)
        self.client.srem(user_following_set, target)
        # 从 target 的关注者集合中移除当前用户
        target_follower_set = follower_key(target)
        self.client.srem(target_follower_set, self.user)

    def is_following(self, target):
        """
        检查当前用户是否正在关注目标用户,
        是的话返回 True ,否则返回 False 。
        """
        # 如果 target 存在于当前用户的正在关注集合中
        # 那么说明当前用户正在关注 target
        user_following_set = following_key(self.user)
        return self.client.sismember(user_following_set, target)

    def get_all_following(self):
        """
        返回当前用户正在关注的所有人。
        """
        user_following_set = following_key(self.user)
        return self.client.smembers(user_following_set)

    def get_all_follower(self):
        """
        返回当前用户的所有关注者。
        """
        user_follower_set = follower_key(self.user)
        return self.client.smembers(user_follower_set)

    def count_following(self):
        """
        返回当前用户正在关注的人数。
        """
        user_following_set = following_key(self.user)
        return self.client.scard(user_following_set)

    def count_follower(self):
        """
        返回当前用户的关注者人数。
        """
        user_follower_set = follower_key(self.user)
        return self.client.scard(user_follower_set)

以下代码展示了社交关系程序的基本使用方法:

>>> from redis import Redis
>>> from relationship import Relationship
>>> client = Redis(decode_responses=True)
>>> peter = Relationship(client, 'peter')  # 这个对象记录的是 peter 的社交关系
>>> peter.follow('jack')  # 关注一些人
>>> peter.follow('tom')
>>> peter.follow('mary')
>>> peter.get_all_following()  # 获取目前正在关注的所有人
set(['mary', 'jack', 'tom'])
>>> peter.count_following()    # 统计目前正在关注的人数
3
>>> jack = Relationship(client, 'jack')    # 这个对象记录的是 jack 的社交关系
>>> jack.get_all_follower()    # peter 前面关注了 jack ,所以他是 jack 的关注者
set(['peter'])
>>> jack.count_follower()      # jack 目前只有一个关注者
1

图 5-10 展示了以上代码创建的各个集合。


图 5-10 社交关系集合示例

../_images/IMAGE_RELATIONSHIP_EXAMPLE.png

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK