redis list / set中的唯一值

时间:2014-10-16 04:15:41

标签: redis nosql

我想在redis中列出现有产品,但我想检查产品名称是否已经存在(重复检查)。

我的列表目前接受重复,因此:任何人都可以帮我展示如何在列表中添加唯一值吗?

6 个答案:

答案 0 :(得分:21)

不使用列表,而是使用集合。集合是唯一对象的容器。每个对象只能在一个集合中出现一次。在这里查看与设置相关的命令:http://redis.io/commands/#set

使用redis-cli的例子(我们尝试两次添加“Product One”,但它只在产品列表中出现一次):

$ redis-cli
127.0.0.1:6379> sadd products "Product One"
(integer) 1
127.0.0.1:6379> sadd products "Product Two"
(integer) 1
127.0.0.1:6379> sadd products "Product Three"
(integer) 1
127.0.0.1:6379> sadd products "Product One"
(integer) 0
127.0.0.1:6379> smembers products
1) "Product Three"
2) "Product One"
3) "Product Two"
127.0.0.1:6379>

答案 1 :(得分:1)

这是我(鲁莽)解决方案,以保持Redis List的独特性。 (在Ruby中实现)

def push_item_to_the_list(LIST_KEY, item)
 insert_status = Redis.linsert(LIST_KEY, 'before', item, item)

 if insert_status == -1
   Redis.lpush(LIST_KEY, item)
 else
   Redis.lrem(LIST_KEY, 1, item)
 end
end

每当您想要推送插入项目到列表时,请检查LINSERT命令是否能够将此项目放在相同的项目(这是我知道检查项目是否已经在redis列表中的唯一方法。)

如果LINSERT将返回状态-1,则表示它无法在列表中找到项目 - 一切正常(您可以推送或立即插入)。

如果LINSERT将返回其他值(在其他情况下列表的大小) - 这意味着它已经能够找到项目并且能够插入另一个项目,就在前一个项目之后。这意味着您的项目(至少一个)重复。你现在可以删除其中一个。

答案 2 :(得分:1)

为什么不在之前致电Redis.lrem?因此,如果它发现任何项目的发生,删除它们,否则将什么都不做。像这样:

def push_item_to_the_list(LIST_KEY, item)
   Redis.lrem(LIST_KEY, 0, item)
   Redis.lpush(LIST_KEY, item)
end

答案 3 :(得分:0)

如果您需要维护顺序和唯一性,您可以使用有序集

127.0.0.1:6379> zadd products 1 "Product One"
(integer) 1
127.0.0.1:6379> zadd products 2 "Product Two"
(integer) 1
127.0.0.1:6379> zadd products 3 "Product Tree"
(integer) 1
127.0.0.1:6379> zadd products 4 "Product Four"
(integer) 1
127.0.0.1:6379> zrange products 0 -1
1) "Product One"
2) "Product Two"
3) "Product Tree"
4) "Product Four"

答案 4 :(得分:0)

我提出了一个创建唯一列表的选项,该列表的元素不会失去位置。该选项比lpush,lrem,rpop的运行速度快得多。同时,它支持sadd,spop的功能。

PHP代码示例:

public function addJobs(array $jobs): int
{
    foreach ($jobs as $key => $job) {
        $hash = hash('md4', $job);
        if (0 === $this->client->hsetnx('QUEUE-HASHES', $hash, 1)) {
            unset($jobs[$key]);
        }
    }

    return $this->client->rpush('QUEUE', $jobs);
}

public function popJobs(int $count): array
{
    if ($count < 1) {
        throw new \InvalidArgumentException('Jobs count must be greater than zero');
    }
    $index = $count - 1;
    $jobs = $this->client->lrange('QUEUE', 0, $index);
    if (\count($jobs)) {
        $this->client->ltrim('QUEUE', $count, -1);
        $hashes = [];
        foreach ($jobs as $job) {
            $hashes[] = hash('md4', $job);
        }
        $this->client->hdel('QUEUE-HASHES', $hashes);
    }

    return $jobs;
}

答案 5 :(得分:0)

redis 5 ZPOPMIN https://redis.io/commands/zpopmin 删除并返回存储在key排序集中的得分最低的成员。

如果未指定,则count的默认值为1。指定比排序集的基数高的count值不会产生错误。返回多个元素时,得分最低的将是第一个,其次是得分较高的元素。