Assuming that myhash is like:
redis 127.0.0.1:6379> HSET myhash field1 "foo"
(integer) 1
redis 127.0.0.1:6379> HSET myhash field2 "bar"
(integer) 1
redis 127.0.0.1:6379> HGETALL myhash
1) "field1"
2) "Hello"
3) "field2"
4) "World"
How can I get number of myhash elements, that is 2, from redis-cli?
I'm learning redis from this tutorial but could not find my answer there.
You can use the HLEN command. Taken directly from the documentation at redis.io:
redis> HSET myhash field1 "Hello"
(integer) 1
redis> HSET myhash field2 "World"
(integer) 1
redis> HLEN myhash
(integer) 2
redis>
Related
Redis has the following data:
key value
code1 num1
code2 num2
...
code6000000 num6000000
I have a known fixed list which is not regular:
{code1, code3, code11, ..., code1234567}
How should I design Redis so that I can easily delete these kv?
Redis has a data structure like hash table this.
you can easily follow instructions there to accomplish your needs.
Example:
redis:6379> HSET myhash field1 "Hello"
(integer) 1
redis:6379> HGET myhash field1
"Hello"
redis:6379> HDEL myhash field1
(integer) 1
if you want to delete some keys that are stored in a Redis list, you can use this one line shell script in Linux:
> redis-cli LRANGE mylist 0 -1 | xargs redis-cli DEL
I need to create a set in Redis:
redis> SADD myset "Hello"
(integer) 1
redis> SADD myset "World"
(integer) 1
redis> SADD myset "World"
(integer) 0
redis> SMEMBERS myset
1) "World"
2) "Hello"
But I need to set expire time for the key myset.
In other words I need a command kind of expire sadd myset... (like SETEX for string values).
Is there any way to execute these commands per one request to Redis server?
There is no built-in command to do this. What you may do is; using transactions. As it is stated in the documentation;
All the commands in a transaction are serialized and executed sequentially. It can never happen that a request issued by another client is served in the middle of the execution of a Redis transaction. This guarantees that the commands are executed as a single isolated operation.
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SADD mynewset a b c d e f g
QUEUED
127.0.0.1:6379> SADD mynewset f g h j k l
QUEUED
127.0.0.1:6379> EXPIRE mynewset 86400
QUEUED
127.0.0.1:6379> EXEC
1) (integer) 7
2) (integer) 4
3) (integer) 1
127.0.0.1:6379> TTL mynewset
(integer) 86394
127.0.0.1:6379>
There is also the possibility of using a Lua script to tie the two commands together:
127.0.0.1:6379> EVAL "redis.call('SADD', KEYS[1], unpack(ARGV)) redis.call('EXPIRE', KEYS[1], 3600)" 1 myset a b c d e
(nil)
127.0.0.1:6379> SMEMBERS myset
1) "c"
2) "d"
3) "a"
4) "b"
5) "e"
127.0.0.1:6379> TTL myset
(integer) 3596
In a redis-cli session:
127.0.0.1:6379> SET somekey "Greetings"
OK
127.0.0.1:6379> SET somekey "Mortal"
OK
127.0.0.1:6379> EXISTS somekey
(integer) 1
I am looking for a function SOMEFUNC that searches for a key and a value. Perhaps something such as:
127.0.0.1:6379> SOMEFUNC "somekey:Greetings"
(integer) 1
127.0.0.1:6379> SOMEFUNC "somekey:Ave"
(integer) 0
It's all driven by a program, so I could use SSCAN on the key and compare, but I'm wondering if there is SOMEFUNC that will do this directly, as the statements above illustrate.
As noted by #MrWiggles, there is no such SOMEFUNC for Strings. On top of the two alternatives that he suggests, another that could get you pretty close is using Hashes instead. Consider the following:
127.0.0.1:6379> HSET somehash "Greetings" ""
(integer) 1
127.0.0.1:6379> HEXISTS somehash "Greetings"
(integer) 1
127.0.0.1:6379> HEXISTS somehash "Mortal"
(integer) 0
127.0.0.1:6379> HEXISTS someotherhash "Ave"
(integer) 0
Sets can also do the same trick:
127.0.0.1:6379> SADD someset "Greetings"
(integer) 1
127.0.0.1:6379> SISMEMBER someset "Greetings"
(integer) 1
127.0.0.1:6379> SISMEMBER someset "Mortal"
(integer) 0
127.0.0.1:6379> SISMEMBER someotherset "Ave"
(integer) 0
That said, note that Hashes & Sets have memory overheads (just like Strings). For 100,000 String/Hash/Set keys, here's what my local Redis' INFO MEMRORY reports for used_memory(_human):
Strings: 9594616 (9.15M)
Hashes: 11194616 (10.68M)
Sets: 25594616 (24.1M)
The real question, however, is why you want to keep everything in separate keys. Unless there's a compelling reason not to do so in your use case, consider a single Hash as a mini-store for all of your "keys" (fields) and values, e.g.:
127.0.0.1:6379> HSET minikv somekey Greetings
(integer) 1
127.0.0.1:6379> HSET minikv anotherkey Human
(integer) 1
...
In terms of your original question, this will bring you back to square one - meaning you'll have to read (HGET minikv somekey) and compare in your app or, my favorite, wrap it in Lua to do it in one call, perhaps like this:
127.0.0.1:6379> EVAL "return redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2] and 1 or 0" 1 minikv somekey Greetings
(integer) 1
127.0.0.1:6379> EVAL "return redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2] and 1 or 0" 1 minikv somekey Mortal
(integer) 0
127.0.0.1:6379> EVAL "return redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2] and 1 or 0" 1 minikv anotherkey Mortal
(integer) 0
127.0.0.1:6379> EVAL "return redis.call('HGET', KEYS[1], ARGV[1]) == ARGV[2] and 1 or 0" 1 minikv anotherkey Human
(integer) 1
The nice thing about using this minikv Hash is the footprint - a 100K Hash INFO memory:
used_memory:8519088
used_memory_human:8.12M
There is nothing built in to Redis that will do this for you.
A couple of ways of achieving this are:
Fetch the value of the key back into your application and then check the value to see if it equals what you want it to
Use a Lua script to do this on the redis server
How do i check hash data exists by hashname?
> hset test record1 data1
> hset test record2 data2
> hset test record3 data3
> hgetall test
127.0.0.1:6379> hgetall test
1) "record1"
2) "data1"
3) "record2"
4) "data2"
5) "record3"
6) "data3"
127.0.0.1:6379> hexists test
(error) ERR wrong number of arguments for 'hexists' command
Thanks In Advance
Try this command, it will solve your problem.
redis> EXISTS test
(integer) 1
You could use HLEN, if that returns zero then they hash does not exist.
redis> HLEN test
(integer) 3
redis> HLEN non_existent_hash_key
(integer) 0
As in the doc http://redis.io/commands/sort
SORT mylist BY weight_*
What I would want to do is something like
SORT mylist BY (weight_* + vote_*)
Is that possible to do this just by Redis?
You can use Lua to build each sum_* key and sort by those:
redis 127.0.0.1:6379> sadd myset 1 2 3
(integer) 0
redis 127.0.0.1:6379> mset weight_1 1 weight_2 2 weight_3 3
OK
redis 127.0.0.1:6379> mset vote_1 1 vote_2 2 vote_3 0
OK
redis 127.0.0.1:6379> eval "for i in ipairs(redis.call('smembers', KEYS[1])) do redis.call('set', 'sum_' .. i, redis.call('get','weight_' .. i) + redis.call('get', 'vote_' .. i)) end;" 1 myset
(nil)
redis 127.0.0.1:6379> sort myset by sum_*
1) "1"
2) "3"
3) "2"