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;
            }
        }
View Code

以上是关于StackExchange.Redis 之 Set集合 类型示例的主要内容,如果未能解决你的问题,请参考以下文章

StackExchange.Redis 之 hash 类型示例

扩展 StackExchange.Redis 支持实体

Redis大幅性能提升之Batch批量读写

Azure Redis 缓存简单设置/获取

#yyds干货盘点#愚公系列2023年03月 .NET CORE工具案例-StackExchange.Redis代码变量方式实现商品秒杀

Redis使用记录