Eyal Ch
Eyal Ch

Reputation: 10066

Redis store lists of values inside Redis hash

My task is to get the list of animals (for example) for a specific user_id.

I don't want to use set/list for each user.

I have tried to use hash where each field is a user_id and each value is a concatenated string of animals. For example: {"1234" : "dog cat", "8477" : "bird dog"}. Here, I can get the animals for user "1234", with just one call to Redis.

I know there is an APPEND command, that appends items to a string. But this is not working for appending to value inside a hash.

I have also tried to use set, and get the values by prefix. For the example above, my set would contain: ("1234:dog", "1234:cat", "8477:bird", "8477:dog"). In order to get all animals for user "1234", I need to search for prefix "1234:". But this is not scale when I have too many items.

What can I do in order to complete my task?

Upvotes: 5

Views: 14351

Answers (3)

for_stack
for_stack

Reputation: 23021

In fact @ruhul's answer is a good solution. However, if you insist on saving all users' info in a single key, you can try the following solution.

Save the information in a HASH as you've tried. When you need to append a new animal to a given user. You can use HGET command to get the animals he already has. Then add the new animal to the string, and use the HSET command to update his animal info.

In order to make it atomic, you can wrap this logic into a Lua scripting.

Upvotes: 0

sazzad
sazzad

Reputation: 6267

If you do not want to keep a separate Set/List for every user but want to get data for each user in optimal way, Redis SortedSet data structure and lexicographical search seems to be your solution.

Keep data in a SortedSet (named animals):

ZADD animals 0 1234:dog 0 1234:cat 0 8477:bird 0 8477:dog

Get data of user 1234 from that SortedSet:

ZRANGEBYLEX animals [1234: (1234;

Output:

1) "1234:cat"
2) "1234:dog"

Upvotes: 12

MD Ruhul Amin
MD Ruhul Amin

Reputation: 4502

Redis' data structures cannot be nested inside other data structures, so storing a List inside a Hash is not possible.

In redis, you are free to create as many keys as you want. So what you can do is to make keys appending user_id and <hash_key>. Maintain a hashSet/list for that key. For example:

user_id:1234 =["dog", "cat"];
user_id:8477 =["bird", "dog"];

Check out the following links for more details:

  1. redis-storing-list-inside-hash
  2. writing-a-query-to-add-multiple-values-to-a-key-in-redis-hashes

Upvotes: 5

Related Questions