Ikke
Ikke

Reputation: 101241

Redis sort gives strange results

I'm trying to find out why I do get these strange results from this sort query:

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> 

I know the data uses , in stead of . and it will be fixed. But why is it sorted so inconsistently? I'd at least expect it to give consistent results (The 9,1's in sequence).

Can anyone explain what's going on here?

Upvotes: 0

Views: 665

Answers (2)

Didier Spezia
Didier Spezia

Reputation: 73256

As mentioned by Ofer, by default, the sort is numeric and the elements are compared as double precision floating point numbers.

Redis sort function works by populating a C array from the original container. The initial order of the items in this array is the order of the items in the initial container (which is undefined for set for instance).

Each item is then tagged with a score value. Redis uses the standard strtod function to convert the string value to a double. This function works with a best effort approach: it tries to convert as many characters as possible. So the "9", "9,1" "9,2" and "9,4" strings will all be converted to 9.0

Finally the array is sorted using either the standard qsort algorithm, either the BENTLEY/McILROY algorithm (depending if limit parameters are set or not). AFAIK, none of these sort algorithms are stable. It means the order of the items with the same score will be random in the result.

This is exactly what you get on the example: you have the "10" items first, and then the "9" items. Order of the "9" items is random.

Upvotes: 2

Ofer Zelig
Ofer Zelig

Reputation: 17498

Add ALPHA at the end:

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

By default, sorting is numeric and elements are compared by their value interpreted as double precision floating point number.

When a list (or set) contains string values and you want to sort them lexicographically, use the ALPHA modifier.

See: http://redis.io/commands/sort

Upvotes: 1

Related Questions