How to use SINTER and ZRANGEBYSCORE together in REDIS - redis

Let's assume that there are three key pattern as user:id, chat:id and message:date that are used for to store data on sets.
Example data (completely fiction scenario):
sadd new:user:id 157
sadd new:user:id 282
sadd chat:id:10354 157
sadd chat:id:10354 282
zadd message:epoch:time 1488877701111 111
zadd message:epoch:time 1488898403636 282
zadd message:epoch:time 1488898409822 157
zadd message:epoch:time 1488899903333 333
I can find which new users had written messages each other on chat id 10354 by using the command of SINTER chat:id:10354 new:user:id.
Also I can find which users has written messages in between 1488880000000 and 1488899999999 by using the command of ZRANGEBYSCORE message:epoch:time 1488880000000 1488899999999.
Question:
Is there any chance to find the new users who had written messages in chat:id:10354 in between 1488880000000 and 1488899999999?

Related

Redis ZRANGEBYLEX matching secondary indexes

I have an index for each user which represents their current score.
I want to find all users with the same score.
Provided that the input is as follows, how can I retrieve only users 1 and 2?
ZADD users 0 1:10
ZADD users 0 2:10
ZADD users 0 3:5
I would expect to do something like mentioned in the docs but I cannot use the key as my index since it is too large (for the post I changed to 1,2,3 so it is not an issue), which is why I set it to 0.
I thought the command could be something like ZRANGEBYLEX users [0:10 (:10 but that returns all 3.
1) "1:10"
2) "2:10"
3) "3:5"
I was able to come up with a solution for this problem, which can further refine as:
Retrieve all users with a given score or retrieve a single score for a single user.
What I determined was that using the namespace users is not a sufficient descriptor for both the score and user id. When using 2 different keys, it is clearly possible to get either a range or a single value. The downside is twice the writes I had hoped, but that is overall not a lot of overhead for me and the only way I found to properly retrieve both score and user.
ZADD score:users 0 10:1
ZADD score:users 0 10:2
ZADD score:users 0 5:3
ZADD users:score 0 1:10
ZADD users:score 0 2:10
ZADD users:score 0 3:5
ZRANGEBYLEX users:score [1: [1:\xff # "1:10"
ZRANGEBYLEX score:users [10: [10:\xff # "10:1" "10:2"

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 !

redis sismember check for multi user online

iam use redis for get online user i just want to check if some user was online or not
first add user to onlines
sadd online_users user_a
(integer) 1
check if user_a is online
sismember online_users user_a
(integer) 1
my question its how to check for multi user if they are online some thing like
add soem users
sadd online_users user_a
(integer) 1
sadd online_users user_b
(integer) 1
sadd online_users user_c
(integer) 1
now i want to check for three users if they are online
sismember online_users {user_a,user_b,user_c}
i dont know if this right but i want for multi user check return data like
{0,1,0} = {offline,online,offline}
The best way to do this is to compare two sets.
1 - hold your 'contacts' in the 1st redis set
SADD contacts:your_id user_1 user_2 user_3 user_4
2- make another set of all connected users
SADD connected user_1 user_2 user_3 user_6 user_78
then use the command SINTER, it will give you the intersection between these two sets which means all of your contacts that are connected
SINTER connected contacts:your_id
just remember to keep the set 'connected' well updated... which is another story
hope this helps.
You'll have to call SISMEMBER for each user independently. In order to streamline the flow and make it more efficient, consider using Lua scripting. For example:
~$ redis-cli SADD online_users user_a user_b user_c
(integer) 3
~$ redis-cli --eval sismmember.lua online_users , user_a user_b user_c foo
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 0
~$ cat sismmember.lua
local rep = {}
local ele = table.remove(ARGV,1)
while (ele) do
rep[#rep+1] = redis.call('SISMEMBER',KEYS[1],ele)
ele = table.remove(ARGV,1)
end
return rep
~$
After redis v6.2.0, we can use SMISMEMBER to check if multiple keys are present in a set
SMISMEMBER online_users user1 user2
response will be
1) (integer) 1
2) (integer) 0
ref: https://redis.io/commands/smismember

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 Sets Not updating value based on key in Redis

I am new to sorted sets in Redis (3.0.2). I basically want to update my value in sorted sets of Redis based on unique key. As of now "zadd" each time keeps on adding new values to a specific key.
As of now:
127.0.0.1:6379> zadd xyz 1 "abc"
(integer) 1
127.0.0.1:6379> zadd xyz 1 "newabc"
(integer) 1
127.0.0.1:6379> zrange xyz 0 -1
1) "abc"
2) "newabc"
Required Output: (It should over write the xyz key's value from "abc" to "newabc"
127.0.0.1:6379> zadd xyz 1 "abc"
(integer) 1
127.0.0.1:6379> zadd xyz 1 "newabc"
(integer) 1
127.0.0.1:6379> zrange xyz 0 -1
1) "newabc"
A sorted set in Redis is a set when we talk about the element, while multiple different elements can coexist with the same score.
If you want that output, you'll need to design a different data model, and since I don't know your actual issue or what's your goal in your project, I won't be able to provide a clear solution.