ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

.Net Redis实战——实现文章投票并排序

2021-01-19 20:03:21  阅读:373  来源: 互联网

标签:redis db Redis 文章 var article Net 排序


本系列文章为学习Redis实战一书记录的随笔。

软件和环境版本:Redis:5.0.7  .Net 5.0 

 

文中不会对Redis基础概念做过多介绍。

Redis数据类型和命令可在菜鸟教程学习:https://www.runoob.com/redis/redis-tutorial.html 。

 

示例介绍

实现一个简单的文章投票功能,并根据文章投票得分进行排序展示。

 

功能设计

使用散列来存储文章信息

article:92617中的冒号只是作为分隔符,可以根据个人信号替换成 | , / 等符号

 

使用两个有序集合来有序地存储文章:第一个有序集合的成员为文章 ID,分值为文章的发布时间;第二个有序集合的成员同样为文章 ID,而分值则为文章的评分。通过这两个有序集合,网站既可以根据文章发布的先后顺序来展示文章,又可以根据文章评分的高低来展示文章。

 

同时为了防止一个用户对一篇文章进行多次投票,需要为每篇文章增加一个投票用户集合存储已投票用户ID。

 

代码实现

代码所用Redis库为StackExchange.Redis。

具体使用参考:https://stackexchange.github.io/StackExchange.Redis/

 

我本机Redis安装在Windows的Linux子系统内,写数据持久化时报错“MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk”。

解决方案:https://blog.csdn.net/u014071875/article/details/103715183 

1.初始化文章,模拟文章发布

[HttpGet("InitArticles")]
        public string InitArticles()
        {
            using (var redis = ConnectionMultiplexer.Connect(redisConnectionStr))
            {
                var db = redis.GetDatabase();
                foreach (var article in Articles)
                {
                    var articleId = $"article:{article.ID}";
                    var hashEntiies = new [] {
                        new HashEntry(nameof(article.Title),article.Title),
                        new HashEntry(nameof(article.Link),article.Link),
                        new HashEntry(nameof(article.Poster),article.Poster),
                        new HashEntry(nameof(article.Votes),article.Votes),
                        new HashEntry(nameof(article.UnixTime),article.UnixTime),
                    };
                    //存储文章信息
                    db.HashSetAsync(articleId, hashEntiies);
                    //将文章信息添加到评分和时间排序的有序集合
                    db.SortedSetAddAsync("score:",articleId, 0);
                    db.SortedSetAddAsync("time:",articleId, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
                    Thread.Sleep(1000);
                }
            }
            return "文章初始化完成";
        }

 

2.文章投票代码

[HttpGet("ArticleVote")]
        public string ArticleVote(int userId,int articleId) {

            using (var redis = ConnectionMultiplexer.Connect(redisConnectionStr))
            {
                var db = redis.GetDatabase();
                if (db.SetAdd($"voted:{articleId}",$"user:{userId}"))
                {
                    //增加投票票数和评分
                    db.HashIncrementAsync($"article:{articleId}", "Votes", 1);
                    db.SortedSetIncrementAsync("score:", $"article:{articleId}", 1);
                }
                else
                {
                    return "不能重复投票";
                }
            }
            return "投票成功";
        }

 

3.获取文章列表(只列出根据评分排序)

[HttpGet("GetArticles")]
        public IEnumerable<Article> GetArticles(int page,int size) {

            var articles = new List<Article>();
            using (var redis = ConnectionMultiplexer.Connect(redisConnectionStr))
            {
                var start = (page - 1) * size;
                var end = start + size - 1;

                var db = redis.GetDatabase();
                var ids = db.SortedSetRangeByRank("score:", start, end,order:Order.Descending);
                foreach (var id in ids)
                {
                    var articleHashEntities = db.HashGetAll(id.ToString());
                    //这里除了用反射没有找到好的解决办法
                    var article = new Article {
                        ID = int.Parse(id.ToString().Split(':')[1]),
                        Title= articleHashEntities.FirstOrDefault(a=>a.Name=="Title").Value,
                        Link= articleHashEntities.FirstOrDefault(a => a.Name == "Link").Value,
                        Poster= int.Parse(articleHashEntities.FirstOrDefault(a => a.Name == "Poster").Value),
                        UnixTime= long.Parse(articleHashEntities.FirstOrDefault(a => a.Name == "UnixTime").Value),
                        Votes= int.Parse(articleHashEntities.FirstOrDefault(a => a.Name == "Votes").Value)
                    };
                    articles.Add(article);
                }
                
            }
            return articles;
        }

 

标签:redis,db,Redis,文章,var,article,Net,排序
来源: https://www.cnblogs.com/Stacking/p/14271482.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有