EBOOK – REDIS IN ACTION

This book covers the use of Redis, an in-memory database/data structure server.

open all | close all

1.3.2 Posting and fetching articles

To post an article, we first create an article ID by incrementing a counter with INCR. We then create the voted SET by adding the poster’s ID to the SET with SADD. To ensure that the SET is removed after one week, we’ll give it an expiration time with the EXPIRE command, which lets Redis automatically delete it. We then store the article information with HMSET. Finally, we add the initial score and posting time to the relevant ZSETs with ZADD. We can see the code for posting an article in listing 1.7.

Listing 1.7
The post_article() function
def post_article(conn, user, title, link):

	article_id = str(conn.incr('article:'))

Generate a new article id.

	voted = 'voted:' + article_id

	conn.sadd(voted, user)
	conn.expire(voted, ONE_WEEK_IN_SECONDS)

Start with the posting user having voted for the article, and set the article voting information to automatically expire in a week (we discuss expiration in chapter 3).

	now = time.time()
	article = 'article:' + article_id

	conn.hmset(article, {
		'title': title,
		'link': link,
		'poster': user,
		'time': now,
		'votes': 1,
	})

Create the article hash.

	conn.zadd('score:', article, now + VOTE_SCORE)
	conn.zadd('time:', article, now)

Add the article to the time and score ordered ZSETs.

return article_id


Okay, so we can vote, and we can post articles. But what about fetching the current top-scoring or most recent articles? For that, we can use ZRANGE to fetch the article IDs, and then we can make calls to HGETALL to fetch information about each article. The only tricky part is that we must remember that ZSETs are sorted in ascending order by their score. But we can fetch items based on the reverse order with ZREVRANGEBYSCORE. The function to fetch a page of articles is shown in listing 1.8.

Listing 1.8
The get_articles() function
ARTICLES_PER_PAGE = 25
def get_articles(conn, page, order='score:'):

	start = (page-1) * ARTICLES_PER_PAGE
	end = start + ARTICLES_PER_PAGE - 1

Set up the start and end indexes for fetching the articles.

	ids = conn.zrevrange(order, start, end)

Fetch the article ids.

	articles = []

	for id in ids:
		article_data = conn.hgetall(id)
		article_data['id'] = id
		articles.append(article_data)

Get the article information from the list of article ids.

return articles


Default Arguments and Keyword Arguments
Inside listing 1.8, we used an argument named order, and we gave it a default value of score:. Some of the details of default arguments and passing arguments as names (instead of by position) can be strange to newcomers to the Python language. If you’re having difficulty understanding what’s going on with function definition or argument passing, the Python language tutorial offers a good introduction to what’s going on, and you can jump right to the particular section by visiting this shortened URL: http://mng.bz/KM5x.

We can now get the top-scoring articles across the entire site. But many of these article voting sites have groups that only deal with articles of a particular topic like cute animals, politics, programming in Java, and even the use of Redis. How could we add or alter our code to offer these topical groups?