答案 0 :(得分:2)
编辑 - 由于我得到了一个downvote(评论解释为什么会很好),我从我的回答中删除了一些混乱。
链接问题中的@DidierSpezia答案是一个很好的答案,但如果要添加/删除范围,则很难维护。然而,构建和维护它并不是一件容易的事(也很昂贵)。
我有一个更容易维护的答案,但是由于需要克隆一组所有范围,因此计算多个范围可能会变得很慢并且内存也很昂贵。
您需要将所有范围保存两次,分为两组。每个范围的得分将是其边界值。
使用@DidierSpezia中的集合示例:
A 2-8
B 4-6
C 2-9
D 7-10
你的两套将是:
ZADD ranges:low 2 "2-8" 4 "4-6" 2 "2-9" 7 "7-10"
ZADD ranges:high 8 "2-8" 6 "4-6" 9 "2-9" 10 "7-10"
要查询值所属的范围,您需要修剪下边框高于查询值的范围,并修剪较高边框较低的范围。
我能想到的最有效的方法是克隆其中一个集合,根据上面给出的规则修剪其中一个边,改变范围的分数以反映另一个边界,然后修剪第二边。
以下是如何找到5属于的范围:
ZUNIONSTORE tmp 1 ranges:low
ZREMRANGEBYSCORE tmp (5 +inf
ZINTERSTORE tmp 2 tmp ranges:high WEIGHTS 0 1
ZREMRANGEBYSCORE tmp -inf (5
ZRANGE tmp 0 -1
答案 1 :(得分:0)
在this discussion中,Dvir Volk和@antirez建议使用一个排序集,其中每个条目代表一个范围,并具有以下形式:
会员=" min-max"范围
分数=最大值
例如:
ZADD z 10 "0-10"
ZADD z 20 "10-20"
ZADD z 100 "50-100"
为了检查某个值是否在某个范围内,您可以使用ZRANGEBYSCORE并解析返回的成员。
例如,要检查值5:
ZRANGEBYSCORE z 5 +inf LIMIT 0 1
这将返回" 0-10"成员,您只需要解析字符串并验证您的值是否介于两者之间。
检查值25:
ZRANGEBYSCORE z 25 +inf LIMIT 0 1
将返回" 50-100",但该值不在该范围之间。