Redis: сопоставление частичных ключей хеша

В хеше у меня есть куча пар ключ-значение

мои ключи имеют следующий формат: name:city

john:newyork
kate:chicago
lisa:atlanta

Я использую python для доступа к Redis и в https://redis-py.readthedocs.org/en/latest/, я не вижу никаких хеш-операций, выполняющих частичное сопоставление

я хотел бы иметь возможность получить все ключи в хеше с названием города

это возможно?


person ealeon    schedule 22.02.2016    source источник


Ответы (2)


Можно, но не с HASH-объектами, а с отсортированными множествами. Пока все элементы в отсортированном наборе имеют одинаковую оценку, вы можете выполнять лексикографическое сопоставление префиксов.

скажем, вы делаете следующее (необработанные команды redis, но то же самое относится и к клиенту python):

ZADD foo 0 john:newyork:<somevalue>
ZADD foo 0 john:chicago:<somevalue>
ZADD foo 0 kate:chicago:<somevalue>
....

Затем вы можете запросить, используя ZRANGEBYLEX:

ZRANGEBYLEX foo [john: (john:\xff

даст вам все записи, которые начинаются с john, и вы можете извлечь значение с помощью регулярных выражений или разделения.

Обратите внимание, что это поиск по префиксу, а не по суффиксу. если вы хотите «все записи в Нью-Йорке», вам нужно изменить порядок в отсортированном наборе.

person Not_a_Golfer    schedule 22.02.2016
comment
хм, я все еще хотел бы иметь O (1) при поиске (в других случаях, когда мне не нужно искать по частичному ключу), поэтому я думаю, что могу иметь как отсортированный набор, так и хэш. это обычная практика? и любой простой способ построить отсортированный набор из хэша? - person ealeon; 24.02.2016
comment
Отсортированные наборы @ealeon имеют доступ O1 к значениям, если вы знаете полный ключ - person Not_a_Golfer; 24.02.2016
comment
я читаю док. я не уверен, возможно ли это, но я мог бы попробовать использовать hscan + match - person ealeon; 24.02.2016

Мне удалось частично добиться совпадения хэш-ключей:

pool = redis.ConnectionPool(host='localhost', port=6379, db=0)
r = redis.StrictRedis(connection_pool=pool)
cmd = "hscan <hashname> 0 match *:atlanta"
print r.execute_command(cmd)
person ealeon    schedule 25.02.2016