laravel - 在 Laravel 中获取两个 Redis 集的交集

标签 laravel redis

我有一个看起来像这样的集合(除了它有大约 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 之间的值

  • 5000 到 8000 之间的 span_minutes

我可以通过首先创建 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"}

因为它是原始集合中唯一符合我的两个条件的元素。

也许我的语法有误,或者方法完全错误。如何有效地获得两个排序集的交集?

最佳答案

正如我在评论中提到的,您需要在客户端进行交集。否则,您必须编写一个 Lua 脚本来完成这项工作:

--inter.lua
local value_key = KEYS[1]
local span_key = KEYS[2]
local value_min = ARGV[1]
local value_max = ARGV[2]
local span_min = ARGV[3]
local span_max = ARGV[4]

local value_range = redis.call("zrangebyscore", value_key, value_min, value_max)
local span_range = redis.call("zrangebyscore", span_key, span_min, span_max)

-- do intersection
local value_set = {}
for _, item in ipairs(value_range) do
    value_set[item] = true
end

local result = {}
for _, item in ipairs(span_range) do
    if value_set[item] ~= nil then table.insert(result, item) end
end

return result

像这样运行:redis-cli --eval inter.lua values spans , 20 100 5000 8000

关于laravel - 在 Laravel 中获取两个 Redis 集的交集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52384916/

相关文章:

php - 添加条件并连接到 laravel 中的连接表

redis - 重启后重新连接到 Redis

php - 如何获取带有偏移量和限制的predis数据?

php - 使用 exec Laravel PHP 运行 .sh 文件

laravel - Elixir 和 Gulp - 复制和连接

php - 带有 UNION 的限制性 WHERE IN SQL 语句

php - 使用 laravel 作为 API 注册新用户

php - 如何将 ZINCRBY 与 predis 一起使用

windows - java.lang.RuntimeException : Can't start redis server. 查看日志了解详情

google-cloud-platform - 如何在使用 Google Cloud Dataflow 清除 Cloud Memorystore 中的缓存后插入数据?