C# 使用Redis实现粉丝好友互粉数据存储和查询
因开发需要加入粉丝关注模块.
在好友关注关系中,主要有以上三种状态,即:
我的粉丝(fans)
我的关注(follow)
互粉(mutual)
设计思路如下:
总体思路我们采用redis里面的zset完成整个功能, 原因是zset有排序(我们要按照关注时间的倒序排列), 去重(我们不能多次关注同一用户)功能. 一个用户我们存贮两个集合, 一个是保存用户关注的人 另一个是保存关注用户的人.
具体命令参考:http://doc.redisfans.com/sorted_set/index.html
用到的命令是:
1、 zadd 添加成员:命令格式: zadd key score member [score …]
2、zrem 移除某个成员:命令格式: zrem key member [member ...]
3、 zcard 统计集合内的成员数:命令格式: zcard key
4、 zrange 查询集合内的成员:命令格式: ZRANGE key start stop [WITHSCORES]
描述:返回指定区间的成员。其中成员位置按 score 值递增(从小到大)来排序。 WITHSCORES选项是用来让成员和它的score值一并返回.
5、 zrevrange跟zrange作用相反
6、zrank获取成员的排名:命令格式: zrank key member
描述:返回有序集key中成员member的排名。成员按 score 值递增(从小到大)顺序排列。排名以0开始,也就是说score 值最小的为0。返回值:返回成员排名,member不存在返回nil.
7、 zinterstore 取两个集合的交集:命令格式:ZINTERSTORE destination numkeys key key ...] [AGGREGATE SUM|MIN|MAX]
描述:计算给定的一个或多个有序集的交集。其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。默认情况下,结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。
返回值:保存到 destination 的结果集成员数。
Redis实现思路
1. 添加关注
添加关注分为两步:
将对方Bid添加到自己的关注A列表中;
Redis::ZADD("A:follow", time(), B)
将自己的Aid添加到对方B的粉丝列表中:
Redis::ZADD("B:fans", time(), A)
2. 取消关注
取消关注同样分为两步:
将对方Bid从自己A的关注A列表中移除;
Redis::ZREM("A:follow", B)
将自己的Aid从对方的粉丝B列表中移除:
Redis::ZREM("B:fans", A)
3. 关注列表
Redis::ZRANGE("A:follow", 0 , -1)
4. 粉丝列表
Redis::ZRANGE("A:fans", 0 , -1)
5. 人物关系
5.1、 单向关注
A单向关注B,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中没有B(或B的关注列表中没有A)。
Redis::ZSCORE("A:fans", B) #未返回分数
Redis::ZSCORE("A:follow", B) #返回分数
5.2、 是否互粉
A和B是否互粉,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中有B(或B的关注列表中有A)。同时成立才为互粉。
Redis::ZSCORE("A:fans", B) #返回分数
Redis::ZSCORE("A:follow", B) #返回分数
6. 数量相关
6.1、 关注数
Redis::ZCARD("A:follow"); #返回数量
6.2、 粉丝数
Redis::ZCARD("A:fans"); #返回数量
7. 排序取出所有的人
7.1、根据关注的时间倒叙取出用户的id
Redis::ZREVRANGE("A:fans", 0, -1, TRUE); #倒序取值
7.2、根据关注时间顺序取出用户的id
Redis::ZRANGE("A:fans", 0, -1, TRUE); #顺序取值
8.获取互粉列表Mutuals
Redis::SInter("A:follow","B:follow");
或
Redis::SInterStore("A_B:follow" , "A:follow","B:follow"); //选存储
Redis::ZRANGE("A_B:follow", 0 , -1)//再获取
具体功能实现 代码分为8个部分
public class RedisFollowHelper{//(FOLLOW_USERS)关注表private static string FOLLOW_USERS = "gz:{0}:follow";//(FANS_USERS)粉丝表private static string FANS_USERS = "gz:{0}:fans";private static string INFO_USERS = "uinfo:{0}";private static int INFO_USERS_TIME = 86400;/// <summary>/// 0.判断是否已经关注了/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>/// <returns></returns>public static bool isFollowed(long cid, long followId){string followUsersKey = string.Format(FOLLOW_USERS, cid);object value = RedisHelper.ZScore(followUsersKey, followId);return value != null;}followId去关注别人,判断是否已关注//public static bool isFollowedByFollowId(long followId, User user)//{// string fanUsersKey = string.Format(FANS_USERS, followId);// Object value = RedisHelper.HGet(fanUsersKey, user.getId().ToString());// return value != null;//}/// <summary>/// 1. 添加关注/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>public static void follow(long cid, long followId){long dt = CFunc.GetTimeStamp(DateTime.Now);//1、将对方id添加到自己的关注列表中;string followUsersKey = string.Format(FOLLOW_USERS, cid);RedisHelper.ZAdd(followUsersKey, (dt, followId));//2、将自己的id添加到对方的粉丝列表中:string fanUsersKey = string.Format(FANS_USERS, followId);RedisHelper.ZAdd(fanUsersKey, (dt, cid));}/// <summary>/// 2. 取消关注/// </summary>/// <param name="cid"></param>/// <param name="followId"></param>public static void unFollow(long cid, long followId){//1、将对方id从自己的关注列表中移除;string followUsersKey = string.Format(FOLLOW_USERS, cid);RedisHelper.ZRem(followUsersKey, followId);//将自己的id从对方的粉丝列表中移除:string fanUsersKey = string.Format(FANS_USERS, followId);RedisHelper.ZRem(fanUsersKey, cid);}/// <summary>/// 3. 关注列表/// </summary>/// <param name="userId">查看者的用户id</param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Follows(long userId, long start = 0, long stop = -1){string followsUsersKey = string.Format(FOLLOW_USERS, userId);string[] objectMap = RedisHelper.ZRange(followsUsersKey, start, stop);return objectMap;}/// <summary>/// 4. 粉丝列表/// </summary>/// <param name="followId"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Fans(long userId, long start = 0, long stop = -1){string fansUsersKey = string.Format(FANS_USERS, userId);string[] objectMap = RedisHelper.ZRange(fansUsersKey, start, stop);return objectMap;}/// <summary>/// 5. 人物关系/// 1.cidA单向关注cidB/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>public static bool LinkAtoB(long cidA, long cidB){string fanKey = string.Format(FANS_USERS, cidA);string followKey = string.Format(FOLLOW_USERS, cidA);//A单向关注B,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中没有B(或B的关注列表中没有A)。if (RedisHelper.ZScore(followKey, cidB) > 0 && RedisHelper.ZScore(fanKey, cidB) == null){return true;}return false;}/// <summary>/// 2.是否互粉/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>/// <returns></returns>public static bool LinkAandB(long cidA, long cidB){string fanKey = string.Format(FANS_USERS, cidA);string followKey = string.Format(FOLLOW_USERS, cidA);//A和B是否互粉,要同时满足两个条件:1、A的关注列表中有B(或B的粉丝列表中有A);2、A的粉丝列表中有B(或B的关注列表中有A)。同时成立才为互粉。if (RedisHelper.ZScore(followKey, cidB) > 0 && RedisHelper.ZScore(fanKey, cidB) > 0){return true;}return false;}/// <summary>/// 6.1、 我的关注数/// </summary>/// <param name="userId"></param>/// <returns></returns>public static long FollowsCount(long userId){string followsCountKey = string.Format(FOLLOW_USERS, userId);long iCount = RedisHelper.ZCard(followsCountKey);return iCount;}/// <summary>/// 6.2、 我的粉丝数/// </summary>/// <param name="userId"></param>/// <returns></returns>public static long FansCount(long userId){string fansCountKey = string.Format(FANS_USERS, userId);long iCount = RedisHelper.ZCard(fansCountKey);return iCount;}/// <summary>/// 7.1根据粉丝添加的时间倒叙取出用户的id/// </summary>/// <param name="cid"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] FansByTimeDesc(long cid, long start = 0, long stop = -1){string fansCountKey = string.Format(FANS_USERS, cid);string[] objectMap = RedisHelper.ZRevRange(fansCountKey, start, stop);return objectMap;}/// <summary>/// 8.获取共同关注列表/// </summary>/// <param name="cidA"></param>/// <param name="cidB"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] Mutuals(long cidA, long cidB, long start = 0, long stop = -1){string followsUsersA = string.Format(FOLLOW_USERS, cidA);string followsUsersB = string.Format(FOLLOW_USERS, cidB);string[] objectMap = RedisHelper.SInter(followsUsersA, followsUsersB);//也可以使用RedisHelper.SInterStore,存储起来再查询if (stop > start){long iCount = objectMap.Length;if (start <= iCount){if (stop > iCount){stop = iCount;}int j = 0;string[] newMap = new string[] { };for (long i = start; i < stop; i++){newMap[j] = objectMap[i];j++;}return newMap;}}return objectMap;}/// <summary>/// 7.2根据关注的时间倒叙取出用户的id/// </summary>/// <param name="cid"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public static string[] FollowByTimeAsc(long cid, long start = 0, long stop = -1){string fansCountKey = string.Format(FOLLOW_USERS, cid);string[] objectMap = RedisHelper.ZRevRange(fansCountKey, start, stop);return objectMap;}public static JObject getUserInfo(long cid, bool Refresh = false){string UsersKey = string.Format(INFO_USERS, cid);string userstr = "";if (Refresh == false){//是否强制刷新数据userstr = RedisHelper.Get(UsersKey);}JObject jo = new JObject();if (string.IsNullOrEmpty(userstr)){//查询数据库数据DataSet ds = ;if (ds.Tables[0].Rows.Count > 0){jo.Add("cid", cid);jo.Add("nickname", CFunc.SafeToStr(ds.Tables[0].Rows[0]["nickname"]));jo.Add("headpic", 1);// CFunc.ObjToInt32(ds.Tables[0].Rows[0]["regtime"]);jo.Add("xkpic", 1);// CFunc.ObjToInt32(ds.Tables[0].Rows[0]["logindate"]);RedisHelper.Set(UsersKey, jo, INFO_USERS_TIME);}ds.Clear();}else{jo = (JObject)JsonConvert.DeserializeObject(userstr);RedisHelper.Expire(UsersKey, INFO_USERS_TIME);}return jo;}internal static bool infoChanged(long cid){string UsersKey = string.Format(INFO_USERS, cid);if (RedisHelper.Exists(UsersKey)){RedisHelper.Del(UsersKey);return true;}return false;}}
C# 使用Redis实现粉丝好友互粉数据存储和查询相关推荐
- MapReduce—案例(六)求互粉好友对
题目: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E,O ...
- MapReduce案例5——求互粉好友对
题目: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E,O ...
- 微博粉丝互粉列表统计
微博粉丝互粉统计 mapper阶段 import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import ...
- python+beautifulsoup/xpath实现新浪微博某互粉好友全部好友圈微博爬虫
主要是懒,想要翻刚刚互粉的好友的全部好友圈微博,然而懒得一个一个去翻,就做了这个. 所谓一切机械性重复工作都可以交给计算机去做,就是我了我这种懒人而生的吧--
- 求好友中互粉的好友对
好友列表: A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E:B,C,D,M,L F:A,B,C,D,E,O,M G:A,C,D,E,F H:A,C,D,E, ...
- 自媒体如何快速涨粉?除了互粉还有这3个方法,能轻松上手
自媒体时代,涨粉成了每个自媒体作者关心的问题.自媒体平台虽然流量大.推荐量也多,但是收益却不是很理想,如果想要月入过万,最好的办法就是涨粉,毕竟粉丝收益还是不错的. 经常有小伙伴遇到这样的问题,为什么 ...
- 计蒜客第七章:互粉攻略
计蒜客习题:互粉攻略 题目 样例 思路 邻接矩阵,mp[0][j]记录粉丝数,mp[i][1]记录关注数,注意重复输入过滤. 代码 #include<iostream> using nam ...
- php微博互粉网站源代码,PHP联合【新浪微博】实现第三方登陆
获取 APP KEY和 APP SECRET 第一步:请求用户授权的token [appkey]&redirect_uri=[回调地址]&response_type=code 请求参数 ...
- Redis实战之好友关注功能
目录 1.关注和取消关注 2.好友关注 - 共同关注 3.好友关注 - Feed 流实现方案 4.好友关注 - 推送到粉丝收件箱 1)传统了分页在 feed 流是不适用的,因为我们的数据会随时发生变化 ...
最新文章
- python发挥_充分发挥 Python 的威力:用最简单的方法打造互联互通的智能产品
- Nuke编辑工具包新版 Cara VR 插件发布
- 记录 之 cat 和 awk gsub 的使用
- 三足鼎立 —— GPM 到底是什么?(一)
- lamp mysql开机自启_centos下设置自启动和配置环境变量的方法
- hikari数据源配置类_Spring中的“多数据源”之详解
- Blazor.Server以正确的方式集成Ids4
- 导航器 Navigator
- 文本框仅可接收decimal
- c# hdf5 写string_Pandas系列之入门篇——HDF5
- “互联网+”时代,漫谈影响用户体验的X因素
- 微PE制作U盘启动盘图文详细教程
- fastadmin 邮件配置
- 4.7开发者日:北极光创投吴峰的投资只管杀不管埋
- 核心业务8:提现+展示还款信息和回款信息
- python爬虫爬取豆瓣电影信息城市_Python爬虫入门 | 2 爬取豆瓣电影信息
- linux刷新分区表,linux磁盘分区的详细步骤(图解linux分区命令使用方法)
- hadoop、hive安装
- 如何在页面上呈现谷歌地图
- 【毕业设计】深度学习实现行人重识别 - python opencv yolo Reid
热门文章
- 下载open jdk 和阿里Alibaba Dragonwell (开源open JDK)
- [深度学习]CNN的基础结构与核心思想
- 前端框架介绍篇(小白专属)
- 上顿号符号_顿号在键盘上怎么打 常见的电脑符号输入方法说明
- VMware Workstation 不可恢复错误: (vmx)Exception 0xc0000006 (disk error while paging) has occurred.
- 正则表达式高级学习技巧
- VS修改项目解决方案名称
- win10锁屏壁纸保存方法
- 记录解决nonebot2中定时器报时区问题的错误
- java布道师_我和 Spring 技术布道师的一天