Redis实践:使用Sets实现关注关系或好友关系

来源:互联网 发布:3d max螺丝数据 编辑:程序博客网 时间:2024/04/30 07:31

         Redis提供了丰富的数据类型,可以使用Redis的 Sets(集合)数据结构来存储关注关系或好友关系。

  具体存储方式如下:对于每一个用户,其关注关系存储两份列表,一份为此用户关注的人的UID列表,另一份为此用户粉丝的UID列表,这两个列表都使用Sets(集合)。比如对于用户ID为123的用户,graph:user:123:following 保存的是其关注人的列表,graph:user:1:followed_by 保存的是关注他的人的列表。

  下面是一个PHP代码的关注关系类,包括了常规的关注关系操作查询等方法,具体可看注释:

 

<? /*  * This example would probably work best if you're using  * an MVC framework, but it can be used standalone as well.  *  * This example also assumes you are using Predis, the excellent  * PHP Redis library available here:  * https://github.com/nrk/predis  */ class UserNode {     // The user's ID, probably loaded from MySQL     private $id;     // The redis server configuration     private $redis_config = array(         array('host' => 'localhost', 'port' => 6379 )     );     // Stores the redis connection resource so that     // we only need to connect to Redis once     private $redis;     public function __construct($userID) {         $this->id = $userID;     }     private function redis() {         if (!$this->redis) {             $this->redis = new Predis\Client($redis_config);         }         return $this->redis;     }     /*      * Makes this user follow the user with the given ID.      * In order to stay efficient, we need to make a two-way      * directed graph. This means when we follow a user, we also      * say that that user is followed by this user, making a forward      * and backword directed graph.      */     public function follow($user) {         $this->redis()->sadd("graph:user:{$this->id}:following", $user);         $this->redis()->sadd("graph:user:$user:followed_by", $this->id);     }     /*      * Makes this user unfollow the user with the given ID.      * First we check to make sure that we are actually following      * the user we want to unfollow, then we remove both the forward      * and backward references.      */     public function unfollow($user) {         if ($this->is_following()) {             $this->redis()->srem("graph:user:{$this->id}:following", $user);             $this->redis()->srem("graph:user:$user:followed_by", $this->id);         }     }     /*      * Returns an array of user ID's that this user follows.      */     public function following() {         return $this->redis()->smembers("graph:user:{$this->id}:following");     }     /*      * Returns an array of user ID's that this user is followed by.      */      public function followed_by() {          return $this->redis()->smembers("graph:user:{$this->id}:followed_by");      }     /*      * Test to see if this user is following the given user or not.      * Returns a boolean.      */     public function is_following($user) {         return $this->redis()->sismember("graph:user:{$this->id}:following", $user);     }     /*      * Test to see if this user is followed by the given user.      * Returns a boolean.      */     public function is_followed_by($user) {         return $this->redis()->sismember("graph:user:{$this->id}:followed_by", $user);     }     /*      * Tests to see if the relationship between this user and the given user is mutual.      */     public function is_mutual($user) {         return ($this->is_following($user) && $this->is_followed_by($user));     }     /*      * Returns the number of users that this user is following.      */     public function follow_count() {         return $this->redis()->scard("graph:user:{$this->id}:following");     }     /*      * Retuns the number of users that follow this user.      */     public function follower_count() {         return $this->redis()->scard("graph:user:{$this->id}:followed_by");     }     /*      * Finds all users that the given users follow in common.      * Returns an array of user IDs      */     public function common_following($users) {         $redis = $this->redis();         $users[] = $this->id;         $keys = array();         foreach ($users as $user) {             $keys[] = "graph:user:{$user}:following";         }         return call_user_func_array(array($redis, "sinter"), $keys);     }     /*      * Finds all users that all of the given users are followed by in common.      * Returns an array of user IDs      */     public function common_followed_by($users) {         $redis = $this->redis();         $users[] = $this->id;         $keys = array();         foreach ($users as $user) {             $keys[] = "graph:user:{$user}:followed_by";         }         return call_user_func_array(array($redis, "sinter"), $keys);     } } ?>


 

 

  下面是使用这个类来操作关注关系的例子:

<? // create two user nodes, assume for this example // they're users with no social graph entries. $user1 = UserNode(1); $user2 = UserNode(2); $user1->follows(); // array() // add some followers $user1->follow(2); $user1->follow(3); // now check the follow list $user1->follows(); // array(2, 3) // now we can also do: $user2->followed_by(); // array(1) // if we do this... $user2->follow(3); // then we can do this to see which people users #1 and #2 follow in common $user1->common_following(2); // array(3) ?>


 


原文链接:http://www.searchdatabase.com.cn/showcontent_52654.htm

原创粉丝点击