fetch all keys from redis which are having some string into it - redis

I am having some data stored in redis with below given keys
I have stored some keys into redis like
key1 = https://abc.net/v/140225014843/css/
key2 = https://abc.net/v/153729007613/css/
key3 = https://abc.net/v/240125414249/css/
key4 = https://abc.net/v/140225014843/css/:tokens
key5 = https://abc.net/v/240125414249/css/:tokens
Now i am having data = 140225014843 i want to fetch key and it's value which is having that data inside it .
Example : key1 is having data inside it so i want to fetch key1 from redis.
I am using django-redis.
Edit :
Key4 is also having data into it but i want to fetch only those keys which are of pattern like key1 .

You should rethink the way you name your keys, as it is an important decision.
You could use a List for each data value you have, with that value being the key and "paths" of that data value being the members of the list.
For example in your case you could do:
redis> RPUSH 140225014843 "css/"
redis> RPUSH 153729007613 "css/"
redis> RPUSH 240125414249 "css/"
redis> RPUSH 140225014843 "css/:tokens"
redis> RPUSH 240125414249 "css/:tokens"
Depending on what is the variable part in your data, you could adjust this approach. For example if "css/" is always present then you could omit it.
Also you may not want duplicates in your lists, in which case you should use a Set instead.

Related

Redis - Check is a given set of ids are part of a redis list/hash

I have a large set of ids (around 100000) which I want to store in redis.
I am looking for the most optimal way through which I can check if a given list of ids, what are the ids that are part of my set.
If I use a redis set, I can use SISMEMBER to check if a id is part of my set, but in this case I want to check if, given a list of ids, which one is part of my set.
Example:
redis> SADD myset "1"
(integer) 1
redis> SADD myset "2"
(integer) 2
redis> MYCOMMAND myset "[1,2,4,5]"
(list) 1, 2
Does anything of this sort exist already ?
thanks !

Filter a list by hash

I would like to store a list of items, filter the items, then move through the results by range.
How would I modify the following query to only return items where display=true?
HSET item1 display true
HSET item2 display false
HSET item3 display true
LPUSH items item1
LPUSH items item2
LPUSH items item3
LRANGE items 0 3
-- returns [item3, item2, item1]
If all you're interested in is expressing a Boolean attribute, just use regular Sets. Adding items is with SADD items:display item1 item3 and getting them back is trivial with SMEMBERS.
Note 1: you need to mind the complexity of any Redis command, and especially so when your N is large (more set members, longer lists...). SMEMBERS can run for a long time in case your set is large so you should consider using the more polite SSCAN variant.
Note 2: Sets (and Sorted Sets) are really useful if you're also looking to do set operations (e.g. union, intersect).
Note 3: Sorted Sets are a super set of regular Sets (:)) so of course you could use them for the same effect but keeping a score that's either 0 or 1 is a little wasteful IMO.
Note 4: another possible direction for you to explore is the use of bitmaps for storing Boolean values - Redis offers a lot of horsepower in that domain.
Let me know if you need more ideas.
Redis doesn't really have a way to get from a list based on hash values. But you can get close by using a sorted set. Instead of storing true/false treat true as 1 and false as 0. Then add your elements to a sorted set.
zadd items 1 item1
zadd items 0 item2
zadd items 1 item3
Now to get items where display==1(true)
zrangebyscore items 1 1
It will return [item1, item3]

How do I know the data type of the value of a given key?

I can't seem to find useful information about Redis commands. I want to know the data type of the value of a given key. For instance to list all the keys of my database I run the following command:
keys *
In my setup, I get the following result:
1) "username:testuser:uid"
2) "uid:1:first"
3) "uid:1:email"
4) "uid:1:hash"
5) "global:next_uid"
6) "members:email"
7) "uid:1:username"
8) "uid:1:last"
9) "uid:1:salt"
10) "uid:1:access"
11) "uid:1:company"
12) "email:testuser#gmail.com:uid"
13) "uid:1:phone_number"
How do I know what data type the key members:email contains? I tried to run get members:email but and I get the error (error) ERR Operation against a key holding the wrong kind of value
Any thoughts?
You could use the type command:
http://redis.io/commands/type
See below from docs:
redis> SET key1 "value"
"OK"
redis> LPUSH key2 "value"
(integer) 1
redis> SADD key3 "value"
(integer) 1
redis> TYPE key1
"string"
redis> TYPE key2
"list"
redis> TYPE key3
"set"
redis>

Redis set operations

Redis Set Operation:
SADD key1 "value1 containing key1"
SADD key1 "value2 containing key1"
SADD key1 "value3 containing key1"
SMEMBERS
Result :
1) "value2 containing key1"
2) "value3 containing key1"
3) "value1 containing key1"
SREM key1 "value2 containing key1" --> it works
Now i want to delete "value2 containing key1" from set, without passing whole value e.g. "value2 containing key1". Want to send only "value2"
SREM key1 "value2"
is there any way to do this ? Or any other method?
Instead of inserting into SET the full value("value1 : verylongmessage"), you can just inserting value("value1") to the set "key1".
BUT you should use another data structure, Hash to store the full content of the value1:
hash['value1'] = "value1 : verylongmessage" (in Redis, you can use HSET?)
So, if you want to delete value1 from the SET, you just delete from both the SET and the HASH.
Hope this can help you ~~~

Is there MGET analog for Redis hashes?

I'm planning to start using hashes insead of regular keys. But I can't find any information about multi get for hash-keys in Redis wiki. Is this kind of command is supported by Redis?
Thank you.
You can query hashes or any keys in pipeline, i.e. in one request to your redis instance. Actual implementation depends on your client, but with redis-py it'd look like this:
pipe = conn.pipeline()
pipe.hgetall('foo')
pipe.hgetall('bar')
pipe.hgetall('zar')
hash1, hash2, hash3 = pipe.execute()
Client will issue one request with 3 commands. This is the same technique that is used to add multiple values to a set at once.
Read more at http://redis.io/topics/pipelining
No MHGETALL but you can Lua it:
local r = {}
for _, v in pairs(KEYS) do
r[#r+1] = redis.call('HGETALL', v)
end
return r
If SORT let you use multiple GETs with the -> syntax, and all your hashes had the same fields, you could get them in a bulk reply by putting their names into a set and sorting that.
SORT names_of_hashes GET *->field1 *->field2 *->field3 *->etc
But it doesn't look like you can do that with the hash access. Plus you'd have to turn the return list back into hashes yourself.
UPDATE: Redis seems to let you fetch multiple fields if you name your hashes nicely:
redis> hset hash:1 name fish
(integer) 1
redis> hset hash:2 name donkey
(integer) 1
redis> hset hash:3 name horse
(integer) 1
redis> hset hash:1 type fish
(integer) 1
redis> hset hash:2 type mammal
(integer) 1
redis> hset hash:3 type mammal
(integer) 1
redis> sadd animals 1
(integer) 1
redis> sadd animals 2
(integer) 1
redis> sadd animals 3
(integer) 1
redis> sort animals get # get hash:*->name get hash:*->type
1. "1"
2. "fish"
3. "fish"
4. "2"
5. "donkey"
6. "mammal"
7. "3"
8. "horse"
9. "mammal"
There is no command to do it on one shot, but there is a way to do it "nicely", using a list (or sorted set) where you would store you hashKeys, and then retrieve them as bulk using multi.
In PHP:
$redis->zAdd("myHashzSet", 1, "myHashKey:1");
$redis->zAdd("myHashzSet", 2, "myHashKey:2");
$redis->zAdd("myHashzSet", 3, "myHashKey:3");
$members = $redis->zRange("myHashzSet", 0, -1);
$redis->multi();
foreach($members as $hashKey) {
$redis->hGetAll($hashKey);
}
$results = $redis->exec();
I recommand using a sorted set, where you use the score as an ID for your hash, it allows to take advantages of all score based command.
Redis has a HMGET command, which returns the values of several hash keys with one command.