【问题标题】:Updating Sorted Set with Redis使用 Redis 更新排序集
【发布时间】:2013-09-08 15:41:11
【问题描述】:

目前我正在尝试更新排序集成员。查看文档,使用ZADD 似乎应该更新成员,如果其分数已经存在。但是,在使用此代码尝试更新成员时,

db.zadd("users", parseInt(key, 10) + 1, JSON.stringify(newData));

....即使分数已经存在,也会添加一个新条目!如何使用 redis 更新排序集成员?

【问题讨论】:

    标签: javascript node.js nosql redis


    【解决方案1】:

    只要条目之间的键和成员匹配,ZADD 就会替换旧成员的分数:

    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"
    

    也许您在 ZADD 命令之间使用了不同的键或成员?

    【讨论】:

    • 感谢您的回答!我想更新分数(数字标识符)的现有成员(值)。我通过一些测试发现,这样做的唯一方法是删除旧记录并重新上传它的新版本。废话,如果分数相同,我希望 redis 添加更新成员的功能!
    • 一个有序集合可以容纳多个具有相同分数的成员。您可以使用新分数更新成员,但使用新成员更新分数没有意义,因为不清楚要删除的内容。如果您只是想添加一个具有给定分数的新成员并删除具有该分数的所有当前成员,您可以为此编写一个 Lua 脚本。如果您详细说明您的用例,我可以给您更好的答案。
    • 当我找到我的记录时,我只是将其数据保存到 JSON 中,然后将其删除。更新我的 JSON 对象后,我以相同的分数重新上传它。
    • 如何将 blah 替换为不同的值?
    【解决方案2】:

    @Eli 已经解释了如何更新元素分数,现在 zadd 添加了@ZettaCircl 解释的新选项,我正在解释如何使用分数和元素通过示例更新元素。

    1. NX = 添加新元素
    2. XX = 更新元素

    将三个国家添加到排序集中

     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
    

    获取分数的国家

    127.0.0.1:6379> zrange country 0 10 withscores
    1) "pakistan"
    2) "1"
    3) "turkey"
    4) "2"
    5) "UK"
    6) "3"
    

    更新国家/地区

    将国家/地区巴基斯坦(元素)更新为新名称使用分数

    127.0.0.1:6379> zadd country xx ch 1 'islamic republic of pakistan'
    (integer) 0 // 0 means not updated
    

    使用元素名称('pakistan')更新巴基斯坦的国家分数

    127.0.0.1:6379> zadd country xx ch 4 'pakistan'
    (integer) 1 // updated successfully 
    

    获取分数的国家

    我们可以在这里看到我们只更新了分数。

    127.0.0.1:6379> zrange country 0 10 withscores
    1) "turkey"
    2) "2"
    3) "UK"
    4) "3"
    5) "pakistan"
    6) "4" // score updated
    

    结论

    我们只能使用元素名称更新排序集中的分数。


    我们如何更新元素

    首先我们需要删除国家 paksitan。

    127.0.0.1:6379> zrem country pakistan
    (integer) 1 // removed successfully
    

    获取分数的国家

    127.0.0.1:6379> zrange country 0 10 withscores
    1) "turkey"
    2) "2"
    3) "UK"
    4) "3"
    

    用新名称添加巴基斯坦

    使用新名称和以前的分数将新元素添加到国家排序集中

    127.0.0.1:6379> zadd country nx 1 'islamic republic of pakistan'
    (integer) 1
    

    获取分数的国家

    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"
    

    结论

    首先我们需要删除元素,然后将新元素添加到排序集中。

    【讨论】:

      【解决方案3】:

      自您 2013 年的回答以来,文档似乎发生了变化。

      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.
      

      来自https://redis.io/commands/zadd

      所以现在,您可以了解 ZADD 的预期行为。鉴于您的回答,选项 XX 可以完成工作。 所以像:

      db.zadd("users", XX, parseInt(key, 10) + 1, JSON.stringify(newData));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-04
        • 2017-03-15
        • 2013-10-14
        • 1970-01-01
        相关资源
        最近更新 更多