redis shows empty set for lrange list - redis

I'm seeing a strange behavior in redis when using the lrange command.
I have a list called "test" with 10000000 values. When I ask for 100 rows starting at 99999 it returns an empty set?!
Any ideas why?
127.0.0.1:6379> keys *
1) "test"
127.0.0.1:6379> type test
list
127.0.0.1:6379> llen test
(integer) 10000000
127.0.0.1:6379> lrange test 99999 100
(empty list or set)

I misunderstood the arguments - it's not like similar commands in other languages.
The stop value is not "how many rows from 'start' should I pull", but rather, "which row should I stop at".
so lrange test 99999 100 meant "start at 99999 end at 100" which makes no sense.
I would have to do lrange test 99999 100099.

Related

Redis HyperLogLog - Too many errors

The scenario is really simple. I'm adding 50 elements (different each time) to a HLL. Usually at the third time, I get a wrong PFCOUNT (151 instead of 150). I know that the HLL has a low error rate but is it so easy to get a false positive ? can this error be handled?
Thanks in advance
Here's the logs.
127.0.0.1:6379> PFADD test DaG4yPCb vrTDeJde SCcK4rvG K0UJPxeT s1RtvWyf EpkUaxhY y4ot0BQW vt13T2eS 5rFe0TKj yXm25gXb 4nnw8YYy Fnqdb4C6 rwuPLUyC W9uS0az7 koOtrENo hIjAa00k eT3VvI7Q zQVhYnYY 1Cshhbbk 8q3B82gH NWlnW5QH fbNYBXoy 4ti95TeI TiUyXs0W TAepHjdd CK26UGuC ESt9opXO ihYIo1L9 0XqFKx8x coh31ZxE 01G7eCjb wJZYByUo ZHfJIKoQ tFGPsdgZ 19DUQvNX 20QtyIVq Xjx4wT9z nJazaXtH cHEqmQjZ hz8j0uhT hpeygfWk hWBf44rU iUJbsPSY nIYDiV80 FgaEU3pI 7EEkDGY6 tPF0KHFM twVbY3wR xFpEg4jP 4JEW0pue
127.0.0.1:6379> PFCOUNT test
(integer) 50
127.0.0.1:6379> PFADD test elapxije pbjtcvbg pjoiaarc pogpnjqd ujzfiuyu kykxhqpl hnkwmwpq gljpsnwu rlnflrdb wexqthqe hwbcgbvt yjdddtpo lnkqcoaz tcjgnxme aiflckyh rfsmwzgw eooownar pkvhdwae tywuoxgv mojqkmqd gepsxhqj cbgrmzih jkormrfk irasppno mmealsye fdumtspr anisssut tuqlufyr coqebpyn zijsoauj akvcvkda jruskmma kalinqpr lsazgswh ozyajcpm edvodqnt befvtsbx bcaurnjh psgdgval pyktekgo kucfjnov xruaulrl rrwqzjac ppbbhdhz iohaeoiq fbztqesn zsfnxzsa masqfqjo fsybqced xzfdhtzv
(integer) 1
127.0.0.1:6379> PFCOUNT test
(integer) 100
127.0.0.1:6379> PFADD test hukqyega olgswnll ufzjkscd oygfsgdu bttlwivr xrvtjsfc criuaabz idxilrvd kitvpuzb ehwrvcip ljthitya clgciaex bagxomaq ziszyehx uuhytedx xycrfcgf nmbnxkav ylxxyyrp rfwniodp vezvqefz gomrekbf tirdnpbp fpbokjjz dwppiomo zgypqxyh kavukjeb wsomngmh oawosnvf tinruzjc bbfqchbn airifskr dqcaznzt vnpfejep jmdlwbek eubhstbo iamgnktp gfojfegy hvmbszlu poauswtc tdgozdfy cxdsprqo pjsuxult nctztxwb fbayirlw dcitezyn zufryoro tisxdwtn mmgztjie vykdkvwm dqogmhnm
(integer) 1
127.0.0.1:6379> PFCOUNT test
(integer) 151
From https://redis.io/commands/PFCOUNT
The returned cardinality of the observed set is not exact, but approximated with a standard error of 0.81%.
In your case it is 1/150~=0.67% which is well within the documented standard error.

How to find in sorted set an element which is just below a certain value

First, I am new to Redis. Well let's say I have done:
127.0.0.1:6379> zadd subs:x 0 0
127.0.0.1:6379> zadd subs:x 500 500
127.0.0.1:6379> zadd subs:x 1000 1000
127.0.0.1:6379> zadd subs:x 5000 5000
127.0.0.1:6379> zadd subs:x 10000 10000
And I want to find an element that is just above the value 2000 and just below.
Above is simple and easy:
127.0.0.1:6379> ZRANGEBYSCORE subs:x 2000 +inf LIMIT 0 1
1) "5000"
But how to find an element below in simple way?
1) I know I can do:
127.0.0.1:6379> ZRANGEBYSCORE subs:x -inf 2000 LIMIT 2 1
1) "1000"
But I have to know before running this command that offset is 2 so in general I have to find offset first.
2) Or I can find ZRANK and then move one step backward:
127.0.0.1:6379> ZRANK subs:x 5000
(integer) 3
127.0.0.1:6379> ZRANGE subs:x 2 2
1) "1000"
So my question is there a simple way to get element just below a certain value?
Like above, but for below, use ZREVRANGEBYSCORE, you should.
Translation from Yoda-speak:
Redis actually features a command that does just what you're looking for - ZREVRANGEBYSCORE. ZREVRANGEBYSCORE does the same thing as ZRANGEBYSCORE but uses reverse ordering (as the "REV" in its name suggests).
That would allow you to get the "below 2000" member easily with just one call, as you've shown in your comment. May the force be with you.

Sorted set of a fixed size in Redis?

I'm a rookie in using Redis, and recently have a problem when I'm thinking the solution to handle the case of high concurrency in out system, I want to use Redis, everybody know access from In-Memory is great faster than IO. Redis sorted set is the possible tool for use to do it, we want to a fixed size of sorted set to contain the user's mobile number, I Googled/Baidued a lot, didn't find any meaning message, so can anybody tell me How to specify Redis Sorted Set a fixed size? And set should tell me any add operation to sorted set is success or not?
Thanks
I don't think you can specify a size, that you will have to check it yourself.
You can use ZCARD
ZCARD KEY
Or you could just remove the first element ZREMRANGEBYRANK
[ZREMRANGEBYRANK][2] [KEY] 0 -[YOURSIZE]
This can be done with a lua script by checking the set size (ZCARD) before adding the element (ZADD). Complexity is O(log(|setsize|)) :
-- KEYS[1] the sorted set
-- ARGV[1] the score
-- ARGV[2] the member
-- ARGV[3] the max size of the sorted set
-- Returns number of elements added
--
if redis.call('ZCARD', KEYS[1]) < tonumber(ARGV[3]) then
return redis.call('ZADD', KEYS[1], ARGV[1], ARGV[2])
else
return 0
end
You can try it out if you save the above snippet as test.lua file and then run it a few times, e.g
redis-cli --eval test.lua myset , 1 A 3
redis-cli --eval test.lua myset , 2 B 3
redis-cli --eval test.lua myset , 3 C 3
redis-cli --eval test.lua myset , 4 D 3
redis-cli --eval test.lua myset , 5 E 3
Verify
127.0.0.1:6379> ZRANGE myset 0 100
1) "A"
2) "B"
3) "C"

How to get DIFF on sorted set

How do I get most weighted elements from a sorted set, but excluding those found in another set(or list or hash).
>zadd all 1 one
>zadd all 2 two
>zadd all 3 three
>sadd disabled 2
>sdiff all disabled
(error) WRONGTYPE Operation against a key holding the wrong kind of value
Is my only option is to get elements from the sorted set one-by-one and compare to the list of "disabled" items? Wouldn't that be very slow because of so many transactions to a server?
What is the approach here?
Note: I assume you've meant sadd disabled two
As you've found out, SDIFF does not operate on sorted sets - that is because defining the difference between sorted sets isn't trivial.
What you could do is first create a temporary set with ZUNIONSTORE and set the intersect's scores to 0. Then do a range excluding the 0, e.g.:
127.0.0.1:6379> ZADD all 1 one 2 two 3 three
(integer) 3
127.0.0.1:6379> SADD disabled two
(integer) 1
127.0.0.1:6379> ZUNIONSTORE tmp 2 all disabled WEIGHTS 1 0 AGGREGATE MIN
(integer) 3
127.0.0.1:6379> ZREVRANGEBYSCORE tmp +inf 1 WITHSCORES
1) "three"
2) "3"
3) "one"
4) "1"

Redis: How to intersect a "normal" set with a sorted set?

Assume I have a set (or sorted set or list if that would be better) A of 100 to 1000 strings.
Then I have a sorted set B of many more strings, say one million.
Now C should be the intersection of A and B (of the strings of course).
I want to have every tuple (X, SCORE_OF_X_IN_B) where X is in C.
Any Idea?
I got two ideas:
Interstore
store A a sorted set with every score being 0
interstore to D
get every item of D
delete D
Simple loop in client
loop over A in my client programm
get zscore for every string
While 1. has way too much overhead on the redis side (Has to write for example. The redis page states quite a high time complexity, too http://redis.io/commands/zinterstore), 2. would have |A| database connections and won't be a good choice.
Maybe I could write a redis/lua script which will work like zscore but with an arbitrary number of strings, but I'm not sure if my hoster allows scripts...
So I just wanted to ask SO, if there is an elegant and fast solution available without scripting!
There is a simple solution to your problem: ZINTERSTORE will work with a SET and a ZSET. Try:
redis> sadd foo a
(integer) 1
redis> zadd bar 1 a
(integer) 1
redis> zadd bar 2 b
(integer) 1
redis> zinterstore baz 2 foo bar AGGREGATE MAX
(integer) 1
redis> zrange baz 0 -1 withscores
1) "a"
2) "1"
Edit: I added AGGREGATE MAX above, since redis will give each member of the (non-sorted) set foo a default score of 1, and SUM that with whatever score it has in the (sorted) set bar.