Recently, some fans and students said to Rabbit: Rabbit, your Redis is very good. But I want to know how to solve the actual problem? So Bunny decided to write one or two Redis combat posts a week starting today
In recent years, more and more websites have begun to offer the ability to vote on web links, articles or questions. The site calculates a score based on when articles were published and how many votes they received, and then uses that score to decide how to rank and display articles.
This article shows you how to use Redis to build a simple post voting site back end.
1 Vote on the article
To build an article voting site, the first thing we need to do is set some numbers and constraints for the site: if an article gets at least 200 “yes” votes, the site considers it interesting; If the site publishes 1,000 articles a day, and 50 of them meet the site’s criteria for interesting articles, all the site has to do is put those 50 articles in the top 100 for at least a day. In addition, the site does not currently offer the ability to vote no.
In order to produce a can over time reduce the score, the program needs to release time and the current time according to the article to calculate the score of the article, the specific calculation method for: articles will be multiplied by a constant, the number of votes and then add the release time of the article, it is concluded that the result is that the article score.
We score articles using the number of seconds that have passed since January 1, 1970, in the UTC time zone, which is commonly referred to as Unix time. The Unix time was chosen because on all platforms where Redis can be run, getting this value in a programming language is fairly straightforward. In addition, the constant for calculating the score multiplied by the number of support votes is 432, which is obtained by dividing the number of seconds in a day (86, 400) by the number of support votes required to present the article in a day (200) : for every support vote an article receives, the program needs to increase the rating of the article by 432 points.
In addition to calculating article ratings, building an article voting site requires the Redis structure to store all kinds of information on the site. For each article on the site, the application uses a hash to store the title of the article, the url pointing to the article, the user who posted the article, the time the article was published, the number of votes the article received, and so on. Here is an example of using hash to store the article information
Our article voting site will use two ordered collections to store articles in order: the member of the first ordered collection is the article ID, and the point value is the post time of the article; The members of the second ordered set are also article ids, and the score is the article rating. With these two ordered collections, websites can display articles either in order of publication or in order of rating, as shown in the figure below.
To prevent users from voting on the same article more than once, the site needs to record a list of users who have voted for each article. To do this, the program creates a collection for each article and uses this collection to store the ids of all the users who have voted, an example of which is shown below.
Before implementing the voting feature, let’s take a look at the following figure: this figure shows what happens to the data structure when user 115423 votes for article 100408.
Now that we know how the site calculates article ratings, and now that we know the data structure the site needs to store data, it’s time to actually implement this voting feature! When a user tries to vote on an article, the program uses the zScORE command to check the ordered set of posts to determine whether the article is less than a week old. If the article is still within the voting time range, the application will use the SADD command to try to add the user to the collection of users who have voted for the article. If the add operation succeeds, then the user is voting for the article for the first time, and the program uses the ZINCRBY command to add 432 points to the score of the article. And update the number of article votes in the hash record using the HINCRBY command (used to increment the value stored in the hash). The pseudocode is as follows
Redis transactions Technically, to implement voting correctly, we need to execute SADD, zINCRBY, and HINCRBY in a single transaction, but we’ll ignore this for now because we’ll cover Redis transactions in a future article.
It’s a pretty good voting feature, right? So how to implement the function of publishing articles?
Post and get articles
Publishing a new article begins by creating a new article ID, which can be done by executing INCR on a counter (counter). The program then needs to use SADD to add the ID of the article publisher to the collection that records the list of users who have voted for the article, and use the ExPIRE command to set an expiration time for the collection. Redis will automatically delete the collection a week after the articles ExPIRE. After that, the program will use HMSET command to store the relevant information of the article, and execute two zADD commands to add the initial score and publication time of the article to the two corresponding ordered collections respectively. The following code shows the ability to publish new articles.
Ok, now that we have the ability to vote for articles and publish articles, the next thing to worry about is how to retrieve the highest rated articles and how to retrieve the latest published articles. To achieve these two functions, the program needs to fetch multiple article ids using the zREVRANGE command, and then execute the HGETALL command once for each article ID to fetch the details of the article. This method can be used to fetch both the highest rated article and the latest published article. It is important to note here that since ordered collections arrange the elements according to their score in ascending order, it is correct to use the zREVRANGE command to retrieve the article ids in ascending order. The article fetch function is shown below.
While our site now shows the most recent posts and top-rated posts, it doesn’t have the group feature that many voting sites now support: a feature that lets users see only posts related to a particular topic, For example, articles about “concurrent programming”, articles about “Python”, articles about “Java programming “, articles about “Redis usage “, etc. Next, Bugs Bunny shows how to add groups to the article voting site.
3 Group the articles
The group function consists of two parts, one part is responsible for recording which group the article belongs to, the other part is responsible for taking out the articles in the group. To keep track of which articles are saved by each group, the site needs to create a collection for each group and record all the ids of articles belonging to the same group into that collection. The following code shows how to add articles to a group and how to remove articles from a group.
At first glance, one might think that using collections to record group posts is not very useful. So far, you’ve only seen the ability of collection structures to check for the presence of an element, but Redis can actually perform operations not only on multiple collections, but even, in some cases, between collections and ordered collections. In order to be able to sort and paging group articles based on scores, a website needs to store all articles in a group into an ordered collection based on scores. Redis’s ZINTERSTORE command can take multiple sets and ordered sets as input, find all the members that exist in both sets and ordered sets, and combine the scores of these members in several different ways (the scores of all set members are treated as 1). For our article voting site, the program needs to use the ZTNTERSTORE command to select the highest score of the same member as the intersection member score: depending on the sorting option used, these score values can be either the article rating or the publication date of the article.
Below is the zINTERSTORE command for a group set with a few articles and an ordered set with a large number of articles and scores. Notice how articles that appear in both the set and the ordered set are added to the resulting ordered set.
A new ordered set score: programming is obtained by the intersection calculation of set groups: programming and ordered set Score:, which contains all members existing in both sets. Because the scores of all members of the set Groups: progzamming are regarded as 1, while the scores of all members of the ordered set Score: are greater than 1, and the points selected by this intersection calculation are the maximum points of the same members. The scores of the members of the ordered set Score: programming are determined by the scores of the members of the ordered set Score
By executing zINTERSTORE command on the collection of stored group articles and the ordered collection of stored article scores, the program can get group articles sorted according to article scores. By executing the ZINTERSTORE command on the collection of stored group articles and the ordered collection of stored article publication time, the program can get group articles sorted according to the publication time of articles. If the group contains a large number of articles, the zINTERSTORE command takes time to execute. To minimize Redis’s workload, the program caches the results of this command for 60 seconds. In addition, we reused the existing get_articles () function to page and get group articles. The following code shows how a website can get a full page of articles from a group.
Some sites only allow users to place articles in one or two groups (one is the “all Articles” group and the other is the group that best fits articles). In this case, it’s best to record the group that the article belongs to directly into the hash that stores the article information, and add a zINCRBY call at the end of the article_vote () function to update the article’s score in the group. But in this example, we build a vote site allows an article belong to multiple groups at the same time (such as an article can belong to the “programming” and “algorithm” at the same time two groups), so for an article belong to multiple groups at the same time, update the article score means that the program needs to articles belonging to a group to perform all the operations. In this case, if an article belongs to many groups, updating the score of the article can become time-consuming, so we cache the results of the zINTERSTORE command in the get_group_articles () function. To minimize the number of zINTERSTORE commands executed. Developers’ choices of flexibility or limitations will change the way applications store and update data. This is true for any database, and Redis is no exception.
Ok, so now we’ve successfully built a website back end that displays the most popular articles, gets them, publishes them, votes on them, and even groups them. If you find the content shown above difficult to understand, or do not understand these examples, you can leave a comment or add tugobi wechat: Yangfujie0214
The “No” example only supports “yes” so far, but there are many real sites where “No” can provide useful feedback. Therefore, find ways to add the ability to vote against article_vote () and post_article () functions. In addition, you can also try to provide users with the ability to switch votes, such as “yes” to “no”, or “no” to “yes”. Prompt. If readers are having trouble implementing the switch vote feature, please refer to Redis’s SMOVE command.