代码之家  ›  专栏  ›  技术社区  ›  Hassan Baig Altons

如何在python中向排序的redis集添加元素

  •  1
  • Hassan Baig Altons  · 技术社区  · 9 年前

    我有一个Django应用程序,用户可以上传照片供公众查看和评论。其中一个要求是上传的照片不能是网站最近看到的照片。为此,我计算了 average (perceptual) hash 上传的每个图像,保存在数据库中。稍后,当放置一个新图像时,它的平均哈希值与最近1000个图像的哈希值相同。

    现在,我想通过将最新的avg哈希保存在 排序redis集 ,而不是我的Postgresql数据库。

    我正在想办法做到这一点。第一步是构建一组avg散列进行比较,确保集合大小保持在1000,并且包含最新的1000个kay值对。

    代码看起来怎么样?

    import redis
    
    POOL = redis.ConnectionPool(host='127.0.0.1', port=6379, db=0)
    
    def insertValue(photo_hash):
        my_server = redis.Redis(connection_pool=POOL)
        try:
            size = my_server.zcard("my_set")
            if size < 1001:
                my_server.zadd("my_set", int(time.time() * 1000), photo_hash)    #time.time() equals seconds since epoch
            else:
               #zrem the element with the lowest score, and then ...
               my_server.zadd("my_set", int(time.time() * 1000), photo_hash)    
        except:
            my_server.zadd("my_set", int(time.time() * 1000), photo_hash)
    

    首先 ,是的语法 zadd 正确(我找不到在线python示例来近似我正在尝试的操作),并且 其次 ,一个如何 zrem 排序集中得分最低的元素?

    1 回复  |  直到 9 年前
        1
  •  1
  •   e4c5    9 年前

    zadd 有点棘手。

    注:参数顺序与官方ZADD不同 命令为了向后兼容,此方法接受 name1、score1、name2、score2的形式,而官方Redis 文档需要score1,name1,score2,name2。

    如果您希望使用标准语法,请考虑使用 StrictRedis类。有关更多信息,请参阅文档的API参考部分 信息

    由于您没有使用StrictRedis,上面的代码所做的就是添加一个名为 time,time()*1000 到名为 my_set 值为的 photo_hash 这似乎很好。因为你两个都有 zrank 和a zscore 函数,它允许您通过名称或值检查是否存在。这些操作非常快。比使用memcached要快得多,因为在使用memcched时,您需要提前获取整个集合。

    同样,对于删除元素,可以使用 zremrangebyrank zremrangebyscore 所以从本质上说,你选择什么作为价值观,你选择了什么作为名称,你选择的价值观并不重要,只要两者都是独一无二的。在你的情况下,它们都可以是独一无二的。

    我看到的唯一改进是使用图像的主键而不是时间。因为有可能两个人同时上传一张图片。