2012-01-25 1 views
0

Я пытаюсь выяснить, почему я получаю эти странные результаты этого рода запроса:Redis рода дает странные результаты

redis> sort set:package:1:all_games by hash:game:*->rating DESC LIMIT 0 10 GET hash:game:*->rating 
1. "10" 
2. "10" 
3. "10" 
4. "9,1" 
5. "9" 
6. "9,2" 
7. "9" 
8. "9,1" 
9. "9" 
10. "9,4" 
redis> 

Я знаю, что данные используются в смену. и он будет исправлен. Но почему это так непоследовательно? Я бы по крайней мере ожидал, что он даст последовательные результаты (9,1 в последовательности).

Может ли кто-нибудь объяснить, что здесь происходит?

ответ

2

Как отметил Офер, по умолчанию, сортировка числовой и элементы сравниваются как числа с плавающей точкой двойной точности.

Функция сортировки Redis работает, заполняя массив C из исходного контейнера. Начальным порядком элементов в этом массиве является порядок элементов в исходном контейнере (который не определен для набора, например).

Каждый элемент затем помечен значком. Redis использует стандартную функцию strtod для преобразования значения строки в double. Эта функция работает с наилучшим подходом: она пытается преобразовать как можно больше символов. Таким образом, строки «9», «9,1» «9,2» и «9,4» будут преобразованы в 9.0

Наконец, массив сортируется с использованием либо стандартного алгоритма qsort, либо the BENTLEY/McILROY algorithm (в зависимости от того, предельные параметры установлены или нет). AFAIK, ни один из этих алгоритмов сортировки не является stable. Это означает, что порядок предметов с одинаковой оценкой будет случайным в результате.

Это именно то, что вы получаете на примере: сначала у вас есть предметы «10», а затем предметы «9». Заказ предметов «9» случайный.

+0

Спасибо за объяснение. Сейчас очень ясно. – Ikke

1

Добавить ALPHA в конце:

sort set:package:1:all_games by hash:game:*->rating DESC LIMIT 0 10 GET hash:game:*->rating ALPHA 

По умолчанию сортировка Числовой и элементы сравниваются их значения интерпретируются как двойной точности с плавающей запятой.

Когда список (или набор) содержит строковые значения и вы хотите их сортировать лексикографически, используйте модификатор ALPHA.

См: http://redis.io/commands/sort

+0

Я пробовал АЛЬФА, но это не то, что мне тоже нужно. Я знал, что 'sort' по умолчанию использует числовую сортировку. Но это был просто вопрос, почему он дает результаты, которые он делает. – Ikke

+0

Сортировка без ALPHA использует версию значений с плавающей запятой. См. Замечательное объяснение @ Дидье, почему «9», «9,1», «9,2», «9,4» обрабатываются одинаково. –