Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redis.py - sorting hashes by particular fields

I am using redis.py and was wondering how I can sort by a given field. I have read the documentation and attempted googling for examples, but haven't found anyhting.

In this case, I have a list of times and the corresponding temperatures. For a given range of 'time', say 1000 to 1100, I'd return the highest values for temp' for a given range of times, assigning it to the variable hightemp. Likewise, I would like to do it with lowtemp too.

Is it possible to do this within redis, as opposed to translating everything back into memory again, as would be the case if I sorted using python

import redis
red = redis.Redis()

red.hmset('temperature', {'time':900, 'temp':123})
red.hmset('temperature', {'time':930, 'temp':123})
red.hmset('temperature', {'time':1000, 'temp':121})
red.hmset('temperature', {'time':1030, 'temp':125})
red.hmset('temperature', {'time':1100, 'temp':126})
red.hmset('temperature', {'time':1130, 'temp':127})
red.hmset('temperature', {'time':1200, 'temp':128})
like image 736
snakesNbronies Avatar asked Jan 16 '23 17:01

snakesNbronies


1 Answers

After pondering this for a while, I have to say it's tricky. The best solution I can come up with is this: Store the data in a sorted set, with time as score and time:temperature as value (to keep the values unique). Then you use ZRANGEBYSCORE to get the wanted subset:

redis 127.0.0.1:6379> zadd temperature 1000 1000:123
(integer) 1
redis 127.0.0.1:6379> zadd temperature 1050 1050:122
(integer) 1
redis 127.0.0.1:6379> zadd temperature 1100 1100:125
(integer) 1
redis 127.0.0.1:6379> zrangebyscore temperature 1000 1100
1) "1000:123"
2) "1050:122"
3) "1100:125"
redis 127.0.0.1:6379> 

These values, however, will be sorted on the score, i.e. the temperature. So you will have to sort the subset in the client instead:

# Result from Redis
result = ['1000:123', '1050:122', '1100:125']
# Weed out the temperatures
temperatures = [int(x.split(':')[1]) for x in result]
# Get max and min temperatures
max_temp, min_temp = max(temperatures), min(temperatures)

It's not super pretty, but it should work. What Lloyd Moore says in his answer is true, and you can sort by fields in hashes, but the SORT command won't let you select a subset easily. I will update this answer if I think of a better solution, or we'll just hope for a healthy discussion in the comments!

Edit: Changed from python sort() to max/min after Didier Speza's advice.

like image 144
Linus Thiel Avatar answered Jan 19 '23 08:01

Linus Thiel