Reverse Pagination Through A Redis Sorted Set

大憨熊 提交于 2020-01-03 12:34:45

问题


Consider a Redis sorted set with the following members:

ZADD mySortedSet 11 "A"
ZADD mySortedSet 21 "B"
ZADD mySortedSet 32 "C"
ZADD mySortedSet 46 "D"
ZADD mySortedSet 53 "E"
ZADD mySortedSet 68 "F"
ZADD mySortedSet 72 "G"
ZADD mySortedSet 82 "H" 
ZADD mySortedSet 94 "I"
ZADD mySortedSet 104 "J"
ZADD mySortedSet 113 "K"

If I want to do pagination in reverse order, starting at an arbitrary slice, I can start with this:

// Returns G, F, E, as expected.
ZREVRANGEBYSCORE mySortedSet 72 (46

Now, knowing only that my upper bound is 46, I can get the previous 3 items in the set, D, C, and B, without knowing the lower bound by doing:

ZREVRANGEBYSCORE mySortedSet 46 -inf LIMIT 0, 3

My question is, how can I get the next 3 items in the set, J, I and H, in that order, knowing only that the upper bound is 72?

// Good start, returns K, J, I, H
ZREVRANGEBYSCORE mySortedSet +inf (72

// Returns K, J, I, due to the offset of 0.  I don't know what the correct offset is because it's from the start of the range, not the end.
ZREVRANGEBYSCORE mySortedSet +inf (72 LIMIT 0, 3

What I think I want is a negative offset, which I don't think is supported.

// Would return J, I, H, but actually returns an empty set.
ZREVRANGEBYSCORE mySortedSet +inf (72 LIMIT -1, 3

I can fake it with a forward range, and then reversing those items, but I'm looking for a native Redis solution, if one exists.

// Returns H, I, J - the items I want, but reversed.
ZRANGEBYSCORE mySortedSet (72 +inf LIMIT 0, 3

Any ideas?

To be clear, I know there is ZRANGE and ZREVRANGE, but in this querying profile, I won't know the actual index, just the score.


回答1:


It's trivial to get the rank for an element, and then work by indexes. Presuming that the only inputs available to your application are the initial score bounds of 72 and 46, you can do this:

redis 127.0.0.1:6379> ZREVRANGEBYSCORE mySortedSet 72 (46
1) "G"
2) "F"
3) "E"
redis 127.0.0.1:6379> ZREVRANK mySortedSet G
(integer) 4
redis 127.0.0.1:6379> ZREVRANGE mySortedSet 1 3
1) "J"
2) "I"
3) "H"
redis 127.0.0.1:6379> 

The only additional call is the O(log(N)) ZREVRANK call. From there, it's a bit of client side math to get the new indexes for the range you're interested in, and ZREVRANGE to get the values you want.

I tested this on Redis 2.6rc5, but it should work on any version over 2.0.



来源:https://stackoverflow.com/questions/11713001/reverse-pagination-through-a-redis-sorted-set

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!