让我们创建5个项目:
HMSET id1 x 0 y 1 z 3
HMSET id2 x 2 y 3 z 5
HMSET id3 x 8 y 4 z 3
HMSET id4 x 9 y 8 z 6
HMSET id5 x 1 y 3 z 5
如何查找0 < x < 2
,2 < y < 5
和4 < z < 8
等元素?
更一般地说,如何使用redis执行多标准搜索?
旁注:在this nice tutorial中,我看了以下通知,是真的吗?
Redis查询
在Redis中,只能通过密钥查询数据。即使我们使用哈希, 我们不能说只要字段......等于......
就能得到钥匙
答案 0 :(得分:2)
本教程是正确的 - Redis不提供开箱即用的搜索功能......但您可以使用Redis的数据结构来维护几乎任何值的索引。
继续您的示例,因为您要查看范围查询,所以您需要使用有序集来存储索引数据。对于每个索引的哈希字段,维护一个单独的有序集,其中成员是键名,分数是字段值。因此,对于您的数据,请执行以下操作:
ZADD _x 0 id1 2 id2 8 id3 9 id4 1 id5
ZADD _y 1 id1 3 id2 4 id3 8 id4 3 id5
ZADD _z 3 id1 5 id2 3 id3 6 id4 5 id5
要执行实际查询,请在每个有序集上使用ZRANGEBYSCORE,并将结果相交以应用逻辑和运算符。这可以在您的应用程序代码中执行,也可以使用服务器端Lua脚本执行。
编辑:这是执行此类查询的Redis Lua脚本。我选择使用Lua,因为我的Node.js技能低于标准(:))并且还因为效率 - 这种方法将节省数据到客户端的往返。:
local tmps = {}
for i = 1, #KEYS / 2, 1 do
local range
range = redis.call("ZRANGEBYSCORE", KEYS[i], "(" .. ARGV[i*2-1], "(" .. ARGV[i*2])
local tmp = KEYS[#KEYS / 2 + i]
redis.call("DEL", tmp)
for k, v in ipairs(range) do
redis.call("SADD", tmp, v)
end
tmps[#tmps + 1] = tmp
end
return redis.call("SINTER", unpack(tmps))
按如下方式调用:
redis-cli --eval query.lua _x _y _z __x __y __z , 0 2 2 5 4 8
请注意,该脚本接受6个键 - 3个索引以及3个临时变量名(根据规范要求,这是集群兼容性所必需的)。
回答评论#1:是 - Redis的排序集分数可以是浮点数,数千个值不应该有任何问题
回答评论#2:没有基准测试我无法确定,但我有充分的理由相信这至少与任何SQL解决方案一样高。
最后,您可能会发现此演示文稿在此背景下非常有用:http://www.slideshare.net/itamarhaber/20140922-redis-tlv-redis-indices