Why redis rpush rq:queue:example-rq 1 does not work - redis

Under Ubuntu 18.04 --
$ redis-cli info
# Server
redis_version:4.0.9
What's magical about rq:queue:example-rq that it fails rpush? --
127.0.0.1:6379> rpush rq:queue:example-rq 1
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
change any one character and it works --
127.0.0.1:6379> rpush rq:queue:example-rp 1
(integer) 1
127.0.0.1:6379> keys *
1) "rq:queue:example-rp"
127.0.0.1:6379> del rq:queue:example-rp
(integer) 1
127.0.0.1:6379> rpush rq:queue:example-qr 1
(integer) 1
127.0.0.1:6379> keys *
1) "rq:queue:example-qr"

Related

redis how to get Sorted Set Member with Score?

I am new to Redis.
127.0.0.1:6379> zadd myset 1 'one'
(integer) 1
127.0.0.1:6379> zadd myset 2 'two'
(integer) 1
127.0.0.1:6379> zadd myset 3 'three' 4 'four'
(integer) 2
127.0.0.1:6379> zadd myset 10 'ten' 9 'nine'
(integer) 2
I tried ZRANGEBYSCORE, but it shows member only..
127.0.0.1:6379> ZRANGEBYSCORE myset -inf +inf
1) "one"
2) "two"
3) "three"
4) "four"
5) "nine"
6) "ten"
But I want to get Score / Member pairs.
How can I get these pairs ?
As #Ersoy already commented:
you need to add WITHSCORES at the end, ZRANGEBYSCORE myset -inf +inf WITHSCORES
The reply is sent in a format as follows:
1) MEMBER_1
2) SCORE_1
3) MEMBER_2
4) SCORE_1
...
If you want the reply as a list/array of pair, like:
1) MEMBER_1, SCORE_1
2) MEMBER_2, SCORE_2
...
Any sane Redis client[1], even in your preferred language, is likely to convert it as such.
[1] not including redis-cli

ZREVRANK 'fair' ranking in REDIS

When I have a sorted set with scores, I'd like to have the right rank even when multiple items have the same score.
For instance, when there are 5 items with scores: 1, 2, 2, 2, 3, I'd like to have those three central items to have the same rank (1), while the highest score gets rank 0 (with ZREVRANGE), and the lowest gets rank 4.
I see that it's possible to query the amount of keys with the same score somewhat efficiently O(log(N)), but it looks like if I want to have the scores as I want them, I'd have to use zscan, which is O(N).
Edit: add complete example based on the accepted solution
Our dataset is a sorted set with scores. For example: a has score 1, b, c and d have score 2, and e has score 3:
127.0.0.1:6379> zadd aset 1 a
(integer) 1
127.0.0.1:6379> zadd aset 2 b
(integer) 1
127.0.0.1:6379> zadd aset 2 c
(integer) 1
127.0.0.1:6379> zadd aset 2 d
(integer) 1
127.0.0.1:6379> zadd aset 3 e
(integer) 1
ZREVRANK works for those items with a unique score:
127.0.0.1:6379> zrevrank aset a
(integer) 4
127.0.0.1:6379> zrevrank aset e
(integer) 0
But it fails for those items with the same score:
127.0.0.1:6379> zrevrank aset b
(integer) 3
127.0.0.1:6379> zrevrank aset c
(integer) 2
127.0.0.1:6379> zrevrank aset d
(integer) 1
To solve that, first get the score with ZSCORE:
127.0.0.1:6379> zscore aset c
"2"
The other items have the same score, of course:
127.0.0.1:6379> zscore aset b
"2"
127.0.0.1:6379> zscore aset d
"2"
To get their rank, just use ZCOUNT with the score:
127.0.0.1:6379> zcount aset (2 +inf
(integer) 1
This also works for those items that have a unique score:
127.0.0.1:6379> zcount aset (1 +inf
(integer) 4
127.0.0.1:6379> zcount aset (3 +inf
(integer) 0
Writing this as an atomic lua script is left as an exercise for the reader.
For a given item with score x, you can determine its rank in O(log(N)) time with ZCOUNT (X +inf.
Exactly how you make use of that will depend on the details of your implementation.
ZREVRANGEBYLEX could be used in this case. The time complexity in this case would be O(log(N)+M) with N being the number of elements in the sorted set and M the number of elements being returned. Please look at ZRANGEBYLEX for syntax.
Lex family of sorted set commands allow you to specify lexicographical ordering for keys with same values.

From redis sorted set, retrieving the rank of the highest value that has score just less than given score

From a redis sorted set, how do I retrieve the rank of highest value that has a score just less than a given score?
For instance, imagine my sorted set is:
rank value score
1) 'a' -10
2) 'd' -4
3) 'c' 0
4) 'b' 2
5) 'e' 10
Specifically, If I'm given the score 12, I want to retrieve rank 5. If I'm given the score 1, I want to retrieve rank 3. If I'm given a score -11, I want to retrieve nothing.
Note #1: rank in a Sorted Set is 0-based
Note #2: you'll have to do two queries, one for finding the element and the other for obtaining its rank.
Example using redis-cli:
127.0.0.1:6379> ZADD z -10 a -4 d 0 c 2 b 10 e
(integer) 5
127.0.0.1:6379> ZREVRANGEBYSCORE z (12 -inf LIMIT 0 1
1) "e"
127.0.0.1:6379> ZRANK z e
(integer) 4
127.0.0.1:6379> ZREVRANGEBYSCORE z (1 -inf LIMIT 0 1
1) "c"
127.0.0.1:6379> ZRANK z c
(integer) 2
127.0.0.1:6379> ZREVRANGEBYSCORE z (-11 -inf LIMIT 0 1
(empty list or set)
Naturally, a Lua script would be ideal for this case, i.e:
$ cat script.lua
local r=redis.call('ZREVRANGEBYSCORE', KEYS[1], '('..ARGV[1], '-inf', 'LIMIT', 0, 1)
if #r > 0 then
r=redis.call('ZRANK', KEYS[1], r[1])
end
return r
$ redis-cli --eval script.lua z , 12
(integer) 4
$ redis-cli --eval script.lua z , 1
(integer) 2
$ redis-cli --eval script.lua z , -11
(empty list or set)

How do I delete the last member of a Redis sorted set?

I am using a command line client. Looks like the ZREM doesn't help much. Now I wonder whether that is possible at all.
To remove the element with the highest rank, use zremrangebyrank <key> -1 -1. Here's an example:
127.0.0.1:6379> zadd test 1 one
(integer) 1
127.0.0.1:6379> zadd test 2 two
(integer) 1
127.0.0.1:6379> zadd test 3 three
(integer) 1
127.0.0.1:6379> zrange test 0 -1
1) "one"
2) "two"
3) "three"
127.0.0.1:6379> zremrangebyrank test -1 -1
(integer) 1
127.0.0.1:6379> zrange test 0 -1
1) "one"
2) "two"

Redis lexicographical ordering doesn't work

I'm trying to create a basic autocomplete feature (I created those below manually to test it out first), but somehow I don't get the result I want after adding some keys.
I add every possible version of a word and keep the exact words with * to mark them (For example, if 10 keys are returned and 3 of them have asterisk, they'll be shown as suggestions), so I can query my hash database after that and get hash results.
There are a few duplicate entry attempts, but since it returns integer 0 for them, I presumed that they weren't added for the second time.
I use Redis 3.0.6
127.0.0.1:6379> zadd zset 0 b
(integer) 1
127.0.0.1:6379> zadd zset 0 ba
(integer) 1
127.0.0.1:6379> zadd zset 0 bar
(integer) 1
127.0.0.1:6379> zadd zset 0 bar*
(integer) 1
127.0.0.1:6379> zadd zset 0 f
(integer) 1
127.0.0.1:6379> zadd zset 0 fo
(integer) 1
127.0.0.1:6379> zadd zset 0 foo
(integer) 1
127.0.0.1:6379> zadd zset 0 foo*
(integer) 1
127.0.0.1:6379> zadd zset 0 foob
(integer) 1
127.0.0.1:6379> zadd zset 0 fooba
(integer) 1
127.0.0.1:6379> zadd zset 0 foobar
(integer) 1
127.0.0.1:6379> zadd zset 0 foobar*
(integer) 1
No problem so far.
I want all words that start with fo
127.0.0.1:6379> zrank zset fo
(integer) 5
It gives five, so I increment by one (like shown here if I get it right) and query all keys.
127.0.0.1:6379> zrange zset 6 -1
1) "foo"
2) "foo*"
3) "foob"
4) "fooba"
5) "foobar"
6) "foobar*"
No problem, I get the desired result.
I keep adding keys.
127.0.0.1:6379> zadd zset 0 a
(integer) 1
127.0.0.1:6379> zadd zset 0 b
(integer) 0
127.0.0.1:6379> zadd zset 0 c
(integer) 1
127.0.0.1:6379> zadd zset 0 fi
(integer) 1
127.0.0.1:6379> zadd zset 0 fil
(integer) 1
127.0.0.1:6379> zadd zset 0 filli
(integer) 1
127.0.0.1:6379> zadd zset 0 fillib
(integer) 1
127.0.0.1:6379> zadd zset 0 fillibo
(integer) 1
127.0.0.1:6379> zadd zset 0 filliboy
(integer) 1
127.0.0.1:6379> zadd zset 0 filliboya
(integer) 1
127.0.0.1:6379> zrank zset fo
(integer) 14
I do another search.
127.0.0.1:6379> zrange zset 15 -1
1) "foo"
2) "foo*"
3) "foob"
4) "fooba"
5) "foobar"
6) "foobar*"
Ok again. I keep adding.
127.0.0.1:6379> zadd zset 0 d
(integer) 1
127.0.0.1:6379> zadd zset 0 e
(integer) 1
127.0.0.1:6379> zadd zset 0 x
(integer) 1
127.0.0.1:6379> zadd zset 0 y
(integer) 1
127.0.0.1:6379> zadd zset 0 z
(integer) 1
127.0.0.1:6379> zadd zset 0 filli*
(integer) 1
127.0.0.1:6379> zadd zset 0 filliboya*
(integer) 1
This is the part where things get interesting. I want to get all the words that start with filli, but I can't. Why?
127.0.0.1:6379> zrank zset filli
(integer) 11
127.0.0.1:6379> zrange zset 12 -1
1) "filli*"
2) "fillib"
3) "fillibo"
4) "filliboy"
5) "filliboya"
6) "filliboya*"
7) "fo"
8) "foo"
9) "foo*"
10) "foob"
11) "fooba"
12) "foobar"
13) "foobar*"
14) "x"
15) "y"
16) "z"
127.0.0.1:6379>
The lexicographical ordering is working, but you're asking for the entire range from the member you've retrieved to the end (-1). Since Redis v2.8 you should be using the ZRANGEBYLEX command for that purpose. In your case, it should be as follows:
ZRANGEBYLEX zset [filli [filli\xff