Currently I am trying to update a sorted set member. Looking at the docs, using ZADD
appears that it should update a member if its score already exists. However, upon using this code to try to update a member,
db.zadd("users", parseInt(key, 10) + 1, JSON.stringify(newData));
....a new entry is added even if a score already exists! How to I update a sorted set member with redis?
Currently I am trying to update a sorted set member. Looking at the docs, using ZADD
appears that it should update a member if its score already exists. However, upon using this code to try to update a member,
db.zadd("users", parseInt(key, 10) + 1, JSON.stringify(newData));
....a new entry is added even if a score already exists! How to I update a sorted set member with redis?
Share Improve this question asked Sep 4, 2013 at 23:45 derek_duncanderek_duncan 1,3771 gold badge13 silver badges22 bronze badges3 Answers
Reset to default 8ZADD will replace an old member's score so long as the key and member match between entries:
redis localhost:6379> ZADD test-key 40 blah
(integer) 1
redis localhost:6379> ZRANGE test-key 0 -1 WITHSCORES
1) "blah"
2) "40"
redis localhost:6379> ZADD test-key 45 blah
(integer) 0
redis localhost:6379> ZRANGE test-key 0 -1 WITHSCORES
1) "blah"
2) "45"
Perhaps you're using different keys or members between ZADD commands?
@Eli already explained how to update element score and now zadd added new options which is explained by @ZettaCircl and I'm explaining how to update element with examples using score and element.
- NX = add new element
- XX = update element
Add three countries into sorted set
127.0.0.1:6379> zadd country nx 1 'pakistan' // nx = add new element
(integer) 1
127.0.0.1:6379> zadd country nx 2 'turkey'
(integer) 1
127.0.0.1:6379> zadd country nx 3 'UK'
(integer) 1
Get country with scores
127.0.0.1:6379> zrange country 0 10 withscores
1) "pakistan"
2) "1"
3) "turkey"
4) "2"
5) "UK"
6) "3"
Update country
Update country Pakistan (element) to new name using score
127.0.0.1:6379> zadd country xx ch 1 'islamic republic of pakistan'
(integer) 0 // 0 means not updated
Update country score of Pakistan using element name ('pakistan')
127.0.0.1:6379> zadd country xx ch 4 'pakistan'
(integer) 1 // updated successfully
Get country with scores
We can see here we updated the score only.
127.0.0.1:6379> zrange country 0 10 withscores
1) "turkey"
2) "2"
3) "UK"
4) "3"
5) "pakistan"
6) "4" // score updated
Conclusion
We can update only score in sorted sets using element name.
How we can update elements
First we need to remove country paksitan.
127.0.0.1:6379> zrem country pakistan
(integer) 1 // removed successfully
Get countries with scores
127.0.0.1:6379> zrange country 0 10 withscores
1) "turkey"
2) "2"
3) "UK"
4) "3"
Add Pakistan with new name
Add new element into country sorted set with new name and previous score
127.0.0.1:6379> zadd country nx 1 'islamic republic of pakistan'
(integer) 1
Get countries with scores
127.0.0.1:6379> zrange country 0 10 withscores
1) "islamic republic of pakistan"
2) "1"
3) "turkey"
4) "2"
5) "UK"
6) "3"
Conclusion
First we need to delete element then add new element into sorted set.
It seems the documentation changed since your 2013 answer.
ZADD options (Redis 3.0.2 or greater)
ZADD supports a list of options, specified after the name of the key and before the first score argument. Options are:
XX: Only update elements that already exist. Never add elements.
NX: Don't update already existing elements. Always add new elements.
CH: Modify the return value from the number of new elements added, to the total number of elements changed (CH is an abbreviation of changed). Changed elements are new elements added and elements already existing for which the score was updated. So elements specified in the command line having the same score as they had in the past are not counted. Note: normally the return value of ZADD only counts the number of new elements added.
INCR: When this option is specified ZADD acts like ZINCRBY. Only one score-element pair can be specified in this mode.
From https://redis.io/commands/zadd
So now, you can tell what behavior you are expected from ZADD. Given your answer, the option XX would do the work. So something like :
db.zadd("users", XX, parseInt(key, 10) + 1, JSON.stringify(newData));