Dynamic sort with Redis

2019-08-29 08:35发布

Let's say I have 5 entries in my Redis database:

  • news::id: the ID of the last news;
  • news::list: a list of all news IDs;
  • news:n where n is the news ID: a hash containing fields such as title, url, etc.;
  • news:n:upvotes: a list of all users' IDs who upvoted the news, thus giving the number of upvotes.
  • news:n:downvotes: a list of all users' IDs who downvoted the news, thus giving the number of downvotes.

Then I have multiple ranking algorithms, where rank =:

  1. upvotes_count;
  2. upvotes_count - downvotes_count;
  3. upvotes_count - downvotes_count - age;
  4. upvotes_count / downvotes_count;
  5. age.

Now how do I sort those news according to each of these algorithms?

I thought about computing the different ranks on every votes, but then if I introduce a new algorithm I need to compute the new rank for all the news.

EVAL could help but it won't be available until v2.6, which surely I don't want to wait for.

Eventually, I could retrieve all the news and put them in a Python list. But again it translates into a high memory usage, not to mention the fact that Redis stores its data in memory.

So is there a proper way to do this or should I just move to MongoDB?

标签: python redis
1条回答
Anthone
2楼-- · 2019-08-29 09:14

You can sort by constants stored in keys.

In your example, I can sort 1. almost trivially using Redis. If you store the other expression values after calculating them, you can sort by them too. For 1., you will need to store the list count somewhere, I will assume news:n:upvotes:count.

The catch is to use the SORT command. For instance, the first sort would be:

SORT news::list BY news:*:upvotes:count GET news:*->title GET news:*->url

...to get titles and urls sorted by upvotes, in crescent order.

There are modifiers too, for alpha sorting, and asc/desc sorting. Read the command page entirely, it is worthwhile.

PS: You can wrap the count, store, sort and possibly deletion of count in a MULTI/EXEC environment (a transaction).

查看更多
登录 后发表回答