ZRANGEBYSCORE
ZRANGEBYSCORE (deprecated)
Начиная с версии Redis 6.2.0, эта команда считается устаревшей.
Её можно заменить на ZRANGE с аргументом BYSCORE при миграции или написании нового кода.
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- Доступно с версии:
- 1.0.5
- Временная сложность:
- O(log(N)+M), где N — количество элементов в упорядоченном наборе, а M — количество возвращаемых элементов. Если M постоянно (например, всегда запрашивается первые 10 элементов с помощью LIMIT), можно считать её O(log(N)).
- Категории ACL:
-
@read,@sortedset,@slow,
Возвращает все элементы в упорядоченном наборе по key со значением между min и max (включая элементы со значением равным min или max). Элементы считаются упорядоченными от меньшего к большему значению.
Элементы с одинаковым значением возвращаются в лексикографическом порядке (это свойство реализации упорядоченного набора в Redis и не требует дополнительных вычислений).
Необязательный аргумент LIMIT можно использовать для получения только определённого диапазона соответствующих элементов (аналогично SELECT LIMIT offset, count в SQL). Отрицательное значение count возвращает все элементы с offset. Имейте в виду, что если offset большое, упорядоченному набору нужно пройти по offset элементам, прежде чем получить необходимые для возврата элементы, что может увеличить временную сложность до O(N).
Необязательный аргумент WITHSCORES заставляет команду возвращать и элемент, и его значение, а не только сам элемент. Этот параметр доступен с версии Redis 2.0.
Исключающие интервалы и бесконечность
min и max могут быть -inf и +inf, поэтому вам не нужно знать наибольшее или наименьшее значение в упорядоченном наборе, чтобы получить все элементы до или от определённого значения.
По умолчанию, интервал, заданный min и max — замкнутый (включающий). Можно задать открытый интервал (исключающий), добавив перед значением символ (. Например:
ZRANGEBYSCORE zset (1 5
Возвратит все элементы со значением 1 < score <= 5 , в то время как:
ZRANGEBYSCORE zset (5 (10
Возвратит все элементы со значением 5 < score < 10 (5 и 10 исключаются).
Возврат
Массив ответов: список элементов в указанном диапазоне значений (при необходимости с их значениями).
Примеры
ZADD myzset 1 "one" ZADD myzset 2 "two" ZADD myzset 3 "three" ZRANGEBYSCORE myzset -inf +inf ZRANGEBYSCORE myzset 1 2 ZRANGEBYSCORE myzset (1 2 ZRANGEBYSCORE myzset (1 (2
Шаблон: взвешенная случайная выборка элемента
Обычно ZRANGEBYSCORE используется просто для получения диапазона элементов, где значение — индексированный целочисленный ключ, но с помощью этой команды можно делать и нестандартные вещи.
Например, распространённая проблема при реализации марковских цепей и других алгоритмов — случайная выборка элемента из набора, но разные элементы могут иметь разные веса, влияющие на вероятность их выбора.
Вот как мы используем эту команду для реализации такого алгоритма:
Представьте элементы A, B и C с весами 1, 2 и 3. Вычисляем сумму весов, которая равна 1+2+3 = 6
На этом этапе добавляем все элементы в упорядоченный набор, используя этот алгоритм:
SUM = ELEMENTS.TOTAL_WEIGHT // 6 in this case.
SCORE = 0
FOREACH ELE in ELEMENTS
SCORE += ELE.weight / SUM
ZADD KEY SCORE ELE
END
Это означает, что вы устанавливаете:
A to score 0.16 B to score .5 C to score 1
Поскольку это приближение, чтобы избежать ситуации, когда C будет равно, например, 0,998 вместо 1, мы просто модифицируем алгоритм, чтобы гарантировать, что последнее значение равно 1 (оставлено как упражнение для читателя...).
На этом этапе, каждый раз, когда нужно получить случайный элемент с весом, вычисляем случайное число от 0 до 1 (что эквивалентно вызову rand() в большинстве языков), и тогда можно сделать:
RANDOM_ELE = ZRANGEBYSCORE key RAND() +inf LIMIT 0 1
История
- Начиная с версии Redis 2.0.0: добавлен модификатор
WITHSCORES.
© 2006–2022 Salvatore Sanfilippo
Licensed under the Creative Commons Attribution-ShareAlike License 4.0.
https://redis.io/commands/zrangebyscore/