【发布时间】:2014-12-11 07:57:36
【问题描述】:
我想在redis 中列出现有产品,但我想先检查产品名称是否已经存在(重复检查)。
我的列表目前接受重复项,所以:谁能帮我展示如何在列表中添加唯一值?
【问题讨论】:
我想在redis 中列出现有产品,但我想先检查产品名称是否已经存在(重复检查)。
我的列表目前接受重复项,所以:谁能帮我展示如何在列表中添加唯一值?
【问题讨论】:
redis 5 ZPOPMIN https://redis.io/commands/zpopmin 删除并返回存储在 key 的排序集中得分最低的 count 个成员。
当未指定时,count 的默认值为 1。指定大于排序集基数的计数值不会产生错误。返回多个元素时,得分最低的将是第一个,其次是得分较高的元素。
【讨论】:
我提出了一个创建唯一列表的选项,其中的元素不会丢失其位置。此选项的工作速度比 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;
}
【讨论】:
为什么不直接打电话给Redis.lrem?因此,如果它发现该项目的任何出现,将其删除,否则将不做任何事情。像这样的:
def push_item_to_the_list(LIST_KEY, item)
Redis.lrem(LIST_KEY, 0, item)
Redis.lpush(LIST_KEY, item)
end
【讨论】:
这是我保持 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
每次当你想push或insert到你的列表时,检查LINSERT命令是否能够把这个项目放在同一个项目之后(这是我知道检查项目是否已经在 redis 列表中的唯一方法。
如果LINSERT 将返回状态 -1,则表示它无法在您的列表中找到项目 - 一切正常(您现在可以推送或插入)。
如果LINSERT 将返回其他值(在其他情况下为列表大小) - 这意味着它已经能够找到项目并且它能够插入另一个项目,就在前一个项目之后。这意味着您的项目有(至少一个)重复项。您现在可以删除其中一个。
【讨论】:
如果您需要保持顺序和唯一性,您可以使用排序集
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"
【讨论】:
不要使用列表,而是使用集合。集合是唯一对象的容器。每个对象在一组中只能出现一次。在此处查看与 set 相关的命令:http://redis.io/commands/#set。
还有一个使用 redis-cli 的例子(我们尝试添加“产品一”两次,但它只出现在产品列表中一次):
$ 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>
【讨论】: