I want to maintain some meta data in redis.
meta_key = build_key()
meta_data = {
"user": 12345,
"tag": "D12321341234123",
}
res = redis_sip.hmset(meta_key, meta_data)
It works as expected.
Now I want to keep a list in this meta_data structure and be able to add element to the list.
For example:
meta_data = {
"user": 12345,
"tag": "D12321341234123",
"items": []
}
But it throws an exception right away:
redis.exceptions.DataError: Invalid input of type: 'list'. Convert to a byte, string or number first.
I reckon I can create a new key and use zadd
to maintain a list. However I would like to minimise the number of key. It is because I need to quickly invalidate the keys once the user signs out. Keeping the keys to bare minimum can help me to
1) quickly evict the keys
2) avoid error because there are less keys to keep a tab on
Is there any way I can keep a list in a redis value and easily expand the list?
2
Answers
yes that’s the way I would do.
however if you want to minimize the key, you have no other way but to stringify the object to text and use set; also parse the string once you get it back.
this would limit you the way to access to single property of the object but you probably already know that.
if you opt for the additional list for each metaKey, you can use pipeline when insert/get/delete the item to reduce no. of round trips.
In most cases,
SADD
orZADD
with pipelining commands will be better. Use a MULTI/EXEC transaction if there is risk another client may get the key in between, therefore getting an incomplete object.Stringify the list in a hash-field may be justifiable in a few cases.
Regarding ‘Quickly evict the keys’, make sure to use
UNLINK
instead ofDEL
.If you choose to stringify, here is how to atomically support insert and remove to a JSON-encoded array in a hash field using Lua and Lua CJSON library:
Insert:
Remove by value:
Usage Example: