How can I sort hset in Redis? - sorting

I would to sort my data with point
redis 127.0.0.1:6379[4]> hset player1 point 2
(integer) 1
redis 127.0.0.1:6379[4]> hset player1 level 5
(integer) 1
redis 127.0.0.1:6379[4]> hset player2 point 1
(integer) 1
redis 127.0.0.1:6379[4]> hset player2 level 9
(integer) 1
redis 127.0.0.1:6379[4]> hset player3 point 10
(integer) 1
redis 127.0.0.1:6379[4]> hset player3 level 5
(integer) 1
Is there a way that return me a list in what way?
player3
player1
player2

You cant sort HSET response in redis. But you can use Redis sorted set instead of a hashmap:
ZADD players 2 player1
ZADD players 1 player2
ZADD players 10 player3
Now you can sort all your players by score:
ZREVRANGE players 0 -1
You can use both HGET and ZREVRANGE if you want to store additional data. So, you'll use ZREVRANGE to get the keys of best players and GET, HGET or HGETALL to get any additional data you need. But in this case you'll need to maintain both sorted set and hashmap:
HMSET player1 name Peter level 5
HMSET player2 name John level 9
HMSET player3 name Michael level 5
ZADD players 2 player1 1 player2 10 player3

Related

How to convert layers of many-to-one relationships into input data without losing information?

I apologize if the question doesn't make much sense.
I'm trying to convert data into inputs for a classifier. I have multiple layers of many to one data which I need to "attach" to the top layer. I will try to explain with an example:
Let's say you have a household, each household contains at least one person (represented with categorical data male/female/other), each person has some amount of pets (represented with categorical data dog/cat/rat/etc..). Is it possible to represent this data into one row (for the household) without losing information?
One way I could think of doing it was the count of the amount of data for each category, so a household would have 2 males, 1 female, 2 dogs and 1 cat. Except this loses the information about how the data itself is structured, like if the female has all of the pets, that data doesn't tell you that.
The other way would be structuring each household into a database, so each row is a person containing m/f/o and the amount of each pet, then performing some dimensionality reduction technique to put it all on one row for the household but I'm not sure if this is feasible.
So yeah, any advice would be appreciated.
have you tried using the one-hot-encoding method to represent each on a single line? Or does this method work?
import pandas as pd
df = pd.DataFrame({'household':["M","M","F","M","F","F"],
'pets': ["Cat","Dog","Cat","Hamster","Dog","Cat"],
'amount of pets': [2,1,1,2,2,3]})
df=pd.get_dummies(df,columns=["pets"])
print(df)
household amount of pets pets_Cat pets_Dog pets_Hamster
0 M 2 1 0 0
1 M 1 0 1 0
2 F 1 1 0 0
3 M 2 0 0 1
4 F 2 0 1 0
5 F 3 1 0 0
print(df.iloc[:1])
household amount of pets pets_Cat pets_Dog pets_Hamster
0 M 2 1 0 0
In this way, it is possible to see both the animal owned by the household and its number in a single line. Is this the representation you want?

Dynamically update ranks of elements in a Redis Sorted Set

In my Go program, I'm working with a Redis Sorted Set called MyEntries that has three elements: EntryA, EntryB and EntryC with rankings 1, 2 and 3 (and so on..).
It's all ordered and elements are unique (that's why I'm not using a LIST).
But then the problem is when ranking order is obviously no longer the case if one element is removed! For example, if I remove EntryB, EntryC would still have ranking 3 (instead of 2).
I know I could basically query by index, since the index number does dynamically change. But I just found out there's, unfortunately, no way in Redis to query index by element name.
Would you please help me solve this issue? Is there any way in Redis to dynamically update rankings in Sorted Sets if one element is removed?
PS I'm building a FIFO queuing program that enables users to also remove elements out of the queue (besides that the oldest leaves first). You'd also like to know what's your position in the queue (that's why I'm facing this ranking update issue).
Instead of putting ranking you may put the score which identifies ranking.
If user a has score of 100, b has score 200 etc..
127.0.0.1:6379> zadd mysort 100 a 200 b 300 c 500 d 50 e
(integer) 5
127.0.0.1:6379> zrevrange mysort 0 -1 withscores
1) "d"
2) "500"
3) "c"
4) "300"
5) "b"
6) "200"
7) "a"
8) "100"
9) "e"
10) "50"
127.0.0.1:6379> zrevrank mysort d
(integer) 0
127.0.0.1:6379> zrevrank mysort e
(integer) 4
127.0.0.1:6379> zrem mysort b
(integer) 1
127.0.0.1:6379> zrevrank mysort e
(integer) 3
127.0.0.1:6379> zrem mysort d
(integer) 1
127.0.0.1:6379> zrevrange mysort 0 -1 withscores
1) "c"
2) "300"
3) "a"
4) "100"
5) "e"
6) "50"
127.0.0.1:6379> zrevrank mysort e
(integer) 2
127.0.0.1:6379> zadd mysort 500 q 25 f 350 p
(integer) 3
127.0.0.1:6379> zrevrange mysort 0 -1 withscores
1) "q"
2) "500"
3) "p"
4) "350"
5) "c"
6) "300"
7) "a"
8) "100"
9) "e"
10) "50"
11) "f"
12) "25"
127.0.0.1:6379> zrevrank mysort q
(integer) 0
In here you keep adding your element into sorted set with their scores, the higher score means the lower ranking - highest score will be 0 when you use zrevrank. when you remove the highest scored element with zrem then the second highest scored element will be highest ranked with the value of 0.

Redis: Group & Sum multiple ZSET Sorted Sets into one Sorted Set

If I have two sorted set with different set of members with different scores:
ZADD set1 10 "player1"
ZADD set1 15 "player2"
ZADD set1 5 "player3"
ZADD set2 30 "player1"
ZADD set2 22 "player3"
I need to merge the above 2 sets by grouping the common all players and summing up their scores and get like this:
set3 40 "player1"
set3 15 "player2"
set3 27 "player3"
One way I tried is to fetch this data into Ruby objects and do the grouping logic. I am looking for ways to do this within Redis.
You're in luck because redis supports this out of the box!
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]
summary: Intersect multiple sorted sets and store the resulting sorted set in a new key
so in your case:
ZINTERSTORE set3 2 set1 set2 AGGREGATE SUM
and voila! set3 contains the common players with summed scores:
127.0.0.1:6379> ZRANGE set3 0 -1 WITHSCORES
1) "player3"
2) "27"
3) "player1"
4) "40"

From edge or arc list to clusters in Stata

I have a Stata dataset that represents connections between users that looks like this:
src_user linked_user
1 2
2 3
3 5
1 4
6 7
I would like to get something like this:
user cluster
1 1
2 1
3 1
4 1
5 1
6 2
7 2
where isid user evaluates to TRUE and I have grouped all users into disjoint clusters. I have tried thinking of this as a reshape problem, but without much success. None of the user-written SNA commands seem to accomplish this as far as I can tell.
What is the most efficient way of doing it with Stata, other than looping, which I am eager to avoid ?
If you reshape the data to long form, you can use group_id (from SSC) to get what you want.
clear
input user1 user2
1 2
2 3
3 5
1 4
6 7
end
gen id = _n
reshape long user, i(id) j(n)
clonevar cluster = id
list, sepby(cluster)
group_id cluster, match(user)
bysort cluster user (id): keep if _n == 1
list, sepby(cluster)

Intersecting Sorted Sets in Redis

I have a sorted set in Redis containing values like those below:
ZADD ranking1 0 Kyle Neath
ZADD ranking1 1 Cameron McEfee
ZADD ranking1 2 Ben Bliekamp
ZADD ranking1 3 Justin Palmer
ZADD ranking2 0 Cameron McEfee
ZADD ranking2 1 Justin Palmer
ZADD ranking2 2 Kyle Neath
ZADD ranking2 3 Ben Bliekamp
... and so on.
Is there a way to fetch the scores for a certain person and return them in list form? As an example, calling Kyle Neath would return [0, 2]. Should I be modeling this differently to achieve the same thing?
With the current layout of the data, the only way to achieve the list is using one zscore per ranking.
Besides this sorted sets, you could have one hash per person with their position in each ranking. The memory usage won't be much higher, since strings are reused and hashes are pretty cheap.
For example:
HMSET "Kyle Neath" ranking1 0 ranking2 2
HMSET "Cameron McEfee" ranking1 1 ranking2 0
HMSET "Ben Bliekamp" ranking1 2 ranking2 3
HMSET "Justin Palmer" ranking1 3 ranking2 1
And to fetch the list
HVALS "Kyle Neath"
But you will have to ensure consistency of the sorted sets and the hashes in your application code.

Resources