ttugates
ttugates

Reputation: 6291

Atomic add/removal of Index(Set) value(s) to Hash properties in Redis

Using Stackexchange.redis, how can I model an index to hash's properties such that I can atomically remove hash index values?

Ex:

Hash       -> Key=1    Value={ FirstName="Bob", LastName="Smith", Etc=...}
              Key=2    Value={ FirstName="Sue", LastName="Smith", Etc=...}

Set(index) -> Key=FirstName:Bob    Value={1}
              Key=FirstName:Sue    Value={2}
              Key=LastName:Smith   Value={1,2}

In the above example, when a new Hash is added with a value of LastName:Smith, I can use .StringAppend() to add a value to its corresponding index(Set).

In the event I need to remove Hash with Key=2, how do I atomically remove 2 from the values stored in the index(Set) Key=LastName:Smith?

Do I need to adjust my model to accommodate a more efficient index for the purpose of querying Hashes by property?

Any adjustment to my verbiage that adds clarity is also appreciated.

~Thanks

Update with what I Learned:

Upvotes: 1

Views: 890

Answers (1)

Imaskar
Imaskar

Reputation: 2939

If you need atomicity, you have to use EVAL or MULTI. For example:

Add element

eval "redis.call('hset',KEYS[1],KEYS[2],KEYS[3],KEYS[4],KEYS[5]) redis.call('sadd',KEYS[2]..':'..KEYS[3],KEYS[1]) redis.call('sadd',KEYS[4]..':'..KEYS[5],KEYS[1])" 5 3 FirstName Bob LastName Marley

127.0.0.1:6370> smembers LastName:Marley
1) "3"
127.0.0.1:6370> hgetall 3
1) "FirstName"
2) "Bob"
3) "LastName"
4) "Marley"

Remove element

eval "local k2=redis.call('hget',KEYS[1],KEYS[2]) local k3=redis.call('hget',KEYS[1],KEYS[3]) redis.call('srem',KEYS[2]..':'..k2,KEYS[1]) redis.call('srem',KEYS[3]..':'..k3,KEYS[1]) redis.call('del',KEYS[1])" 3 3 FirstName LastName

127.0.0.1:6370> hgetall 3
(empty list or set)
127.0.0.1:6370> smembers LstName:Marley
(empty list or set)

Upvotes: 1

Related Questions