>>> conn.sadd('better_zoo', 'tiger', 'wolf', 'duck')
0
Пересечение множеств (получение общих членов) zoo и better_zoo:
>>> conn.sinter('zoo', 'better_zoo')
{b'duck'}
Выполним пересечение множеств zoo и better_zoo и сохраним результат в множестве fowl_zoo:
>>> conn.sinterstore('fowl_zoo', 'zoo', 'better_zoo')
1
Есть кто живой?
>>> conn.smembers('fowl_zoo')
{b'duck'}
Выполним объединение (всех членов) множеств zoo и better_zoo:
>>> conn.sunion('zoo', 'better_zoo')
{b'duck', b'goat', b'wolf', b'tiger'}
Сохраним результат этого пересечения в множестве fabulous_zoo:
>>> conn.sunionstore('fabulous_zoo', 'zoo', 'better_zoo')
4
>>> conn.smembers('fabulous_zoo')
{b'duck', b'goat', b'wolf', b'tiger'}
Какие элементы присутствуют в множестве zoo и отсутствуют в множестве better_zoo? Используйте метод sdiff(), чтобы получить разность множеств, и метод sdiffstore(), чтобы сохранить ее в множестве zoo_sale:
>>> conn.sdiff('zoo', 'better_zoo')
{b'goat'}
>>> conn.sdiffstore('zoo_sale', 'zoo', 'better_zoo')
1
>>> conn.smembers('zoo_sale')
{b'goat'}
Один из самых гибких типов данных Redis — это
• списков лидеров;
• вторичных индексов;
• временных рядов, где отметки времени используются как счетчик.
Мы рассмотрим последний вариант применения, отслеживая логины пользователей с помощью временных меток. Мы будем использовать значение времени epoch (подробнее об этом — в главе 10), которое возвращает функция time():
>>> import time
>>> now = time.time()
>>> now
1361857057.576483
Добавим первого гостя (он немного нервничает):
>>> conn.zadd('logins', 'smeagol', now)
1
Пять минут спустя добавим второго гостя:
>>> conn.zadd('logins', 'sauron', now+(5*60))
1
Через два часа:
>>> conn.zadd('logins', 'bilbo', now+(2*60*60))
1
Еще один гость не торопился и пришел спустя сутки:
>>> conn.zadd('logins', 'treebeard', now+(24*60*60))
1
Каким по счету пришел bilbo?
>>> conn.zrank('logins', 'bilbo')
2
Когда это было?
>>> conn.zscore('logins', 'bilbo')
1361864257.576483
Посмотрим, каким по счету пришел каждый гость:
>>> conn.zrange('logins', 0, -1)
[b'smeagol', b'sauron', b'bilbo', b'treebeard']
И когда:
>>> conn.zrange('logins', 0, -1, withscores=True)
[(b'smeagol', 1361857057.576483), (b'sauron', 1361857357.576483),
(b'bilbo', 1361864257.576483), (b'treebeard', 1361943457.576483)]
Биты — это очень эффективный (с точки зрения занимаемого места) и быстрый способ обработать большое множество чисел. Предположим, у вас есть сайт, на котором регистрируются пользователи. Вы хотите отслеживать, как часто люди авторизуются, сколько пользователей посещает сайт в конкретный день, как часто один и тот же пользователь посещает сайт в следующие дни и т. д. Вы могли бы использовать множества Redis, но если вы присваиваете пользователям увеличивающиеся числовые ID, биты помогут вам быстрее и компактнее решить эту задачу.
Начнем с создания последовательности битов для каждого дня. Для этой проверки мы используем всего три дня и несколько ID:
>>> days = ['2013-02-25', '2013-02-26', '2013-02-27']
>>> big_spender = 1089
>>> tire_kicker = 40459
>>> late_joiner = 550212
Каждая дата является отдельным ключом. Установим бит для конкретного пользователя в эту дату. Например, в первую дату (2013-02-25) у нас есть посещения от big_spender (ID 1089) и tire_kicker (ID 40459):
>>> conn.setbit(days[0], big_spender, 1)
0
>>> conn.setbit(days[0], tire_kicker, 1)
0
На следующий день big_spender вернулся: