StackExchange.Redis 之 Set集合 类型示例
Posted 找.net工作(北京)
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了StackExchange.Redis 之 Set集合 类型示例相关的知识,希望对你有一定的参考价值。
话不多说直接上代码:
// set添加单个元素 stopwatch.Start(); var isok = RedisCacheHelper.Instance.SetAdd("setkey", "10"); stopwatch.Stop(); Console.WriteLine("set添加单个元素消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); // set添加多个元素 sting类型集合 List<string> strlist = new List<string>() { "1", "2", "A", "B", "你", "好" }; stopwatch.Start(); var getlong = RedisCacheHelper.Instance.SetAdd("setkeylist", strlist); stopwatch.Stop(); Console.WriteLine("set添加多个元素消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); Console.WriteLine("返回集合长度:" + getlong); //从数据库获取10条数据 stopwatch.Start(); var getlist = TestRedis.GetOrderFormAll(10); stopwatch.Stop(); Console.WriteLine("从数据库获取10条数据消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); // set添加多个对象集合 序列化 stopwatch.Start(); var getvalue = RedisCacheHelper.Instance.SetAddList("setkeyobjlist", getlist); stopwatch.Stop(); Console.WriteLine("set添加多个对象集合消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); Console.WriteLine("返回集合长度:" + getvalue);
// 获取set集合的长度 var getleng = RedisCacheHelper.Instance.SetLength("setkeylist"); Console.WriteLine("获取 setkeylist 的长度:" + getleng); var getobjleng = RedisCacheHelper.Instance.SetLength("setkeyobjlist"); Console.WriteLine("获取 setkeyobjlist 的长度:" + getobjleng); // 检查元素是否属于Set集合 var getisA = RedisCacheHelper.Instance.ExistsInSet("setkeylist", "A"); var getisC = RedisCacheHelper.Instance.ExistsInSet("setkeylist", "C"); Console.WriteLine("检查 A 是否属于setkeylist集合:" + getisA); Console.WriteLine("检查 C 是否属于setkeylist集合:" + getisC); // 根据key获取所有Set元素 stopwatch.Start(); var getlist = RedisCacheHelper.Instance.GetMembers("setkeylist"); stopwatch.Stop(); Console.WriteLine("获取所有Set元素消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getlist) { Console.WriteLine(item); } // 根据key获取所有对象元素 反序列化 stopwatch.Start(); var getobjlist = RedisCacheHelper.Instance.GetAllMembers<OrderForm>("setkeyobjlist"); stopwatch.Stop(); Console.WriteLine("获取所有对象集合消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getobjlist) { Console.WriteLine("打印Area: " + item.Area); }
//求 交集、差集、并集 string[] arry2 = { "setkeylist", "setkeylist2" }; var d1 = RedisCacheHelper.Instance.GetCombines(SetOperation.Union, arry2.ToList()); //并集 var d2 = RedisCacheHelper.Instance.GetCombines(SetOperation.Intersect, arry2.ToList()); //交集 var d3 = RedisCacheHelper.Instance.GetCombines(SetOperation.Difference, arry2.ToList()); //差集 foreach (var item in d1) { Console.WriteLine("setkeylist和setkeylist2的并集有:" + item); } foreach (var item in d2) { Console.WriteLine("setkeylist和setkeylist2的交集有:" + item); } foreach (var item in d3) { Console.WriteLine("setkeylist和setkeylist2的差集有:" + item); }
// 根据key随机获取Set中的1个元素 循环获取会得到重复内容, for (int i = 0; i < 5; i++) { stopwatch.Start(); var getone = RedisCacheHelper.Instance.GetRandomMember("setkeyobjlist"); stopwatch.Stop(); //Console.WriteLine("根据key随机获取Set中的1个元素消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); Console.WriteLine("打印: " + getone); } // 根据key随机获取Set中的n个元素 一次性获取,无重复值 stopwatch.Start(); var getobjlist = RedisCacheHelper.Instance.GetRandomMembers("setkeyobjlist", 5); stopwatch.Stop(); Console.WriteLine("根据key随机获取Set中的n个元素消耗时间:" + stopwatch.ElapsedMilliseconds.ToString()); foreach (var item in getobjlist) { Console.WriteLine("打印: " + item); }
应用场景:
Redis set 对外提供的功能与 list 类似是一个列表的功能,特殊之处在于 set 是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set 是一个很好的选择,并且 set 提供了判断某个成员是否在一个 set 集合内的重要接口,这个也是 list 所不能提供的。
实现方式:
set 的内部实现是一个 value 永远为 null 的 HashMap,实际就是通过计算 hash 的方式来快速排重的,这也是 set 能提供判断一个成员是否在集合内的原因。
最后附上Helper帮助类
/// <summary> /// set添加单个元素 /// 具有唯一性 比如在线人数/点赞人数/收藏人数等 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="db"></param> /// <returns></returns> public bool SetAdd(string key, string value, TimeSpan? span = null, int db = -1) { try { _db = GetDatabase(db); //设置过期时间 if (span != null) { this.KeyExpire(key, span); } return _db.SetAdd(key, value); } catch (Exception ex) { return false; } } /// <summary> /// set添加多个元素集合 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="db"></param> /// <returns></returns> public long SetAdd(string key, List<string> arryList, int db = -1) { try { _db = GetDatabase(db); RedisValue[] valueList = arryList.Select(u => (RedisValue)u).ToArray(); return _db.SetAdd(key, valueList); } catch (Exception) { return 0; } } /// <summary> /// set添加多个对象集合 序列化 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="db"></param> /// <returns></returns> public long SetAddList<T>(string key, IEnumerable<T> list, int db = -1) where T : class { try { _db = GetDatabase(db); List<RedisValue> listRedisValue = new List<RedisValue>(); foreach (var item in list) { string json = JsonConvert.SerializeObject(item); listRedisValue.Add(json); } return _db.SetAdd(key, listRedisValue.ToArray()); } catch (Exception) { return 0; } } /// <summary> /// 获取set集合的长度 /// </summary> /// <param name="key"></param> /// <param name="db"></param> /// <returns></returns> public long SetLength(string key, int db = -1) { try { _db = GetDatabase(db); return _db.SetLength(key); } catch (Exception) { return 0; } } /// <summary> /// 检查元素是否属于Set集合 /// </summary> /// <param name="key"></param> /// <param name="value"></param> /// <param name="db"></param> /// <returns></returns> public bool ExistsInSet(string key, string value, int db = -1) { try { _db = GetDatabase(db); return _db.SetContains(key, value); } catch (Exception) { return false; } } /// <summary> /// 根据key获取所有Set元素 /// </summary> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public IEnumerable<string> GetMembers(string redisKey, int db = -1) { try { _db = GetDatabase(db); var rValue = _db.SetMembers(redisKey); return rValue.Select(ob => ob.ToString()); } catch (Exception) { throw; } } /// <summary> /// 根据key获取所有Set对象集合 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public List<T> GetAllMembers<T>(string redisKey, int db = -1) where T : class { List<T> result = new List<T>(); try { _db = GetDatabase(db); var arr = _db.SetMembers(redisKey); foreach (var item in arr) { if (!item.IsNullOrEmpty) { var t = JsonConvert.DeserializeObject<T>(item); if (t != null) { result.Add(t); } } } } catch (Exception) { return null; } return result; } /// <summary> /// 根据key随机获取Set中的1个元素 不删除该元素 /// 可应用于中奖类的案例 /// </summary> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public string GetRandomMember(string redisKey, int db = -1) { try { _db = GetDatabase(db); var rValue = _db.SetRandomMember(redisKey); return rValue.ToString(); } catch (Exception) { throw; } } /// <summary> /// 根据key随机获取Set中的n个元素 不删除该元素 /// 可应用于中奖类的案例 /// </summary> /// <param name="redisKey"></param> /// <param name="count"></param> /// <param name="db"></param> /// <returns></returns> public IEnumerable<string> GetRandomMembers(string redisKey, long count, int db = -1) { try { _db = GetDatabase(db); var rValue = _db.SetRandomMembers(redisKey, count); return rValue.Select(ob => ob.ToString()); } catch (Exception) { throw; } } /// <summary> /// 随机删除指定key集合中的一个值,并返回这些值 /// 可应用于抽奖类的案例 /// </summary> /// <param name="redisKey"></param> /// <param name="db"></param> /// <returns></returns> public string GetRandomRemovePop(string redisKey, int db = -1) { try { _db = GetDatabase(db); var rValue = _db.SetPop(redisKey); return rValue.ToString(); } catch (Exception) { throw; } } /// <summary> /// 随机删除指定key集合中的n个值,并返回这些值 /// 可应用于抽奖类的案例 /// </summary> /// <param name="redisKey"></param> /// <param name="count"></param> /// <param name="db"></param> /// <returns></returns> public IEnumerable<string> GetRandomRemovePops(string redisKey, long count, int db = -1) { try { _db = GetDatabase(db); var rValue = _db.SetPop(redisKey, count); return rValue.Select(ob => ob.ToString()); } catch (Exception) { throw; } } /// <summary> /// 返回指定rediskey集合的交集、差集、并集 /// 只能在同一个库内查询,跨库则不行 /// </summary> /// <param name="operation"></param> /// <param name="keyList"></param> /// <param name="db"></param> /// <returns></returns> public IEnumerable<string> GetCombines(SetOperation operation, List<string> keyList, int db = -1) { try { _db = GetDatabase(db); RedisKey[] valueList = keyList.Select(u => (RedisKey)u).ToArray(); var rValue = _db.SetCombine(operation, valueList); return rValue.Select(ob => ob.ToString()); } catch (Exception) { throw; } }
以上是关于StackExchange.Redis 之 Set集合 类型示例的主要内容,如果未能解决你的问题,请参考以下文章
StackExchange.Redis 之 hash 类型示例
#yyds干货盘点#愚公系列2023年03月 .NET CORE工具案例-StackExchange.Redis代码变量方式实现商品秒杀