【发布时间】:2018-09-19 18:25:36
【问题描述】:
我有一个这样的集合(除了它有大约 8000 个项目):
{"id":563244,"stock_id":693,"value":"9.17","span_minutes":1440,"symbol":"BCS"}
{"id":565527,"stock_id":10093,"value":"21.09","span_minutes":2880,"symbol":"GDXS"}
{"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
{"id":565269,"stock_id":8883,"value":"127.60","span_minutes":5760,"symbol":"SAA"}
现在,我想要的是获取条目:
值在 20 到 100 之间
span_minutes 在 5000 到 8000 之间
我可以通过首先创建 2 个新的排序集然后使用 zrangebyscore 提取我想要的条目来获得这些:
ZADD values 9.17 '{"id":563244,"stock_id":693,"value":"9.17","symbol":"BCS"}'
ZADD values 21.09 {"id":565527,"stock_id":10093,"value":"21.09","span_minutes":2880,"symbol":"GDXS"}
ZADD values 91.52 {"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
ZADD values 127.60 {"id":565269,"stock_id":8883,"value":"127.60","span_minutes":5760,"symbol":"SAA"}
ZADD spans 1440 '{"id":563244,"stock_id":693,"value":"9.17","symbol":"BCS"}'
ZADD spans 2880 {"id":565527,"stock_id":10093,"value":"21.09","span_minutes":2880,"symbol":"GDXS"}
ZADD spans 7200 {"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
ZADD spans 5760 {"id":565269,"stock_id":8883,"value":"127.60","span_minutes":5760,"symbol":"SAA"}
现在,如果我想过滤这些集合以获得我想要的值,我可以这样做:
$value_range = Redis::zrangebyscore('values',20,100);
$span_range = Redis::zrangebyscore('spans',5000,8000);
这些分别返回:
1) {"id":565527,"stock_id":10093,"value":"21.09","span_minutes":2880,"symbol":"GDXS"}
2) {"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
和
1) {"id":565269,"stock_id":8883,"value":"127.60","span_minutes":5760,"symbol":"SAA"}
2) {"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
现在我需要的是一种将这两组结合起来的方法。从我在 Redis 文档中看到的内容来看,我应该能够为此目的使用 zinterstore,但我不理解语法,无论我尝试什么都会抛出错误或返回整数 0。例如:
Redis::zinterstore('intersection', 2, $value_range, $span_range); 返回错误。
$intereseciton = Redis::zinterstore(2, $value_range, $span_range); 返回 0。
我应该得到的是:
1) {"id":564311,"stock_id":4241,"value":"91.52","span_minutes":7200,"symbol":"NDAQ"}
因为它是原始集合中唯一符合我的两个条件的元素。
也许我有错误的语法,或者完全错误的方法。如何有效地获得两个排序集的交集?
【问题讨论】:
-
你必须在客户端做交集。
-
@for_stack 为什么?这不是 interstore 命令的用途吗?要返回出现在两个集合中的条目?
-
因为
zrangebyscore的结果是在客户端,而不是存储在Redis中。zinterstore只能做存储在 Redis 中的集合的交集。 -
@for_stack 明白了。那么你知道另一种在 Redis 中完全实现我的目标的方法还是我必须在客户端上工作?
-
如果你坚持要在服务器端相交,你可以写一个Lua脚本来完成这项工作。检查我的答案。