It would be useful to be able to SORT BY the score associated with a key in a sorted set.
Use Case: You have a huge sorted set, player_scores, keeping track of the scores of every player in an online game. This allows fast calculation of the top k players for displaying on a leaderboard. You also want to be able to show leaderboards for a subset of users based on queries over fields like team affiliation, level, character race etc. You could do a ZINTERSTORE over the player_scores zset and sets containing all the players in each category (team 3, level 7, dwarf etc.), but this incurs the cost of sorting the entire result set, which may be many orders of magnitude larger than the number of entries you actually want to display on the leaderboard (100 say). The most efficient way to calculate the ad-hoc leaderboards would be to perform the appropriate set operations over ordinary sets to get the set of players eligible for the leaderboard and then do "SORT eligible_players BY player_scores->* LIMIT 0 100", where I am pretending that the Hash lookup syntax works for sorted sets. This syntax seems appropriate since retrieving the score of a key in a zset is just a matter of looking it up in the zset's underlying hash table.
There are many equivalent use cases to this like returning products, web pages or houses filtered by categories and ranked by popularity, price etc. In any scenario in which you want a global ranking as well as rankings on filtered datasets, it would save space to only store the scores once - in the global ranking zset.
Comment From: ghost
+1 for this feature. I'd like a way to query redis for a key's rank and score - this would allow me to pipeline queries for a subset of keys (like a team of players as the previous poster mentioned)
Comment From: huangzhw
@oranagra Now we have patterns like 'abc', 'abc->field', do we need pattern like abc->*, so we can sort by field or score?
Comment From: oranagra
I'm ok with extending SORT to be able to look into sorted sets the same way it does for hashes.
and also make it possible to use the * substitution for the field name (on a constant key), rather than a constant field on a substituted key.
However, the SORT command is a very bad command in many ways, and i feel that we may wanna aim to deprecate it rather than extend it.
So realizing there's a use case, maybe we need to think of other ways to solve it. I see the top comment says that ZINTERSTORE would have been an option had it has a LIMIT option. These days, we also have ZINTER, and soon also ZINTERCARD (which does have a LIMIT argument). Maybe we want to extend the ZINTER and ZINTERSTORE commands with a LIMIT option too? But actually this means the the entries you get are not necessarily the ones with the best score (unlike SORT)
@itamarhaber WDYT?
Comment From: itamarhaber
The use case is indeed common in the leaderboard context. As far as I know, the heavy rollers (if anyone can verify this I'd appreciate it) maintain a zset per "facet" and fan out score updates to all of these. That approach is more nosql-ish in the sense that data is denormalized (duplicated) and the structure is optimized for read operations.
An extended ZINTER[STORE] would allow such reads ad-hoc with the price of computational complexity, so while we can provide it I'm unsure if that's a pattern we should promote. In any case, my half-baked 2c is that the extended variant needs to be more SCAN-like, where the 1st zset is intersected against a capped range of the rest.
Comment From: itamarhaber
As for extending SORT, generally, I'd be against doing any work on that command as it is (almost?) broken. That said, I wouldn't reject a PR just because of that.