Unique value in the redis list / set

I want to create a list of existing products in redis , but I want to check if the product name already exists (double check).

My list currently accepts duplicates, therefore: Can someone help me show how to add a unique value to the list?

+10
source share
5 answers

Instead of using a list, use a set. Installations are containers for unique objects. Each object can be displayed only once in a set. Take a look at the set-related commands: http://redis.io/commands/#set .

And an example of using redis-cli (we try to add “Product one” twice, but it appears only once in the list of products):

 $ 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> 
+22
source

This is my (reckless) decision to keep the Redis List unique. (implementation in 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 

Each time you want to click or paste an item into your list, check to see if the LINSERT command LINSERT put that item immediately after the same item (this is the only way to find out if that item is already in the redis list or not).

If LINSERT returns the status -1, it means that he could not find the item in your list - everything is in order (you can click it or paste it now).

If LINSERT returns a different value (the size of the list in another case), it means that he was able to find the element already, and he was able to insert another element immediately after the previous one. This means that you have ( at least ) duplication of your element. Now you can delete one of them.

+1
source

Why not just call Redis.lrem before? Therefore, if he finds any occurrences of the subject, he will delete them, otherwise he will not do anything. Like that:

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

If you need to maintain order and uniqueness , you can use a sorted set

 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" 
0
source

I propose an option that creates a unique list whose elements do not lose their position. This option works much faster than lpush, lrem, rpop. At the same time, it supports sadd, spop functionality.

PHP code example:

 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; } 
0
source

Source: https://habr.com/ru/post/976815/


All Articles