Zeroing all Sorted Set Scores
I'm using Redis to store a set of checksums. I'm incrementing each member that I see while parsing a large dataset, and using the score to determine which I've "visited" more than once. However, as this operation is done periodically, I would like to reset the scores of all members to zero afterward. Is there a good way of doing this?
I am aware of ZRANGEBYSCORE, and perhaps could "copy" what it returns into a new key, however with a large set of data, this is less desirable. I could also take the minimum score at the start of the process and ZREMRANGEBYSCORE everything at or below that score, but this too seems undesirable as my scores would continue to rise indefinitely.
You could use ZUNIONSTORE with a WEIGHTS value of zero to copy the set and zero all scores, e.g.
ZUNIONSTORE myZeroedSet 1 myInitialSet WEIGHTS 0 RENAME myZeroedSet myInitialSet
A weight of zero will cause all scores in myInitialSet to be multiplied by zero, thus resetting them. The RENAME will succeed without you having to explicitly delete myInitialSet first.
The advantage of this is that it happens inside Redis (you don't have to transfer the entire set over the network and back), and it's fast.
The best and quickest way to do that is using a simple LUA script :
eval "local z=redis.call('ZRANGE', KEYS, 0, -1) for i=1, #z, 1 do redis.call('ZADD', KEYS, 0, z[i]) end" 1 myInitialSet
It's atomic and everything happens inside Redis too.