lua – 如何使用Redis将搜索文本与其他条件相结合?

lua – 如何使用Redis将搜索文本与其他条件相结合?,第1张

概述我使用Redis成功地编写了文本搜索和其他标准的交集.要实现这一点,我正在使用Lua脚本.问题是我不仅要阅读,还要从该脚本中编写值.从Redis 3.2可以通过调用redis.replicate_commands()来实现这一点,但不能在3.2之前实现. 以下是我存储值的方法. 名称 > HSET product:name 'Cool product' 1> HSET product:name 我使用Redis成功地编写了文本搜索和其他标准的交集.要实现这一点,我正在使用Lua脚本.问题是我不仅要阅读,还要从该脚本中编写值.从Redis 3.2可以通过调用redis.replicate_commands()来实现这一点,但不能在3.2之前实现.

以下是我存储值的方法.

名称

> HSET product:name 'Cool product' 1> HSET product:name 'Nice product' 2

价钱

> ZADD product:price 49.90 1> ZADD product:price 54.90 2

然后,为了获得所有匹配’ice’的产品,我打电话给:

> HSCAN product:name 0 MATCH *ice*

但是,由于HSCAN使用游标,我必须多次调用它来获取所有结果.这是我使用Lua脚本的地方:

local cursor = 0local fIElds = {}local IDs = {}local key = 'product:name'local value = '*' .. ARGV[1] .. '*'repeat    local result = redis.call('HSCAN',key,cursor,'MATCH',value)    cursor = tonumber(result[1])    fIElds = result[2]    for i,ID in ipairs(fIElds) do        if i % 2 == 0 then            IDs[#IDs + 1] = ID        end    enduntil cursor == 0return IDs

因为不可能将脚本的结果与另一个调用一起使用,比如SADD键EVAL(SHA)….而且,在脚本中也不可能使用全局变量.我已经更改了字段循环中的部分以访问脚本外部的ID列表:

if i % 2 == 0 then    IDs[#IDs + 1] = ID    redis.call('SADD',KEYS[1],ID)end

我不得不将redis.replicate_commands()添加到第一行.通过这个更改,我可以从调用脚本时传递的密钥中获取所有ID(参见KEYS [1]).

最后,为了获得列表100产品ID的价格在40到50之间,其中名称包含“ice”,我执行以下 *** 作:

> ZUNIONSTORE tmp:price 1 product:price WEIGHTS 1> ZREMRANGEBYscore tmp:price 0 40> ZREMRANGEBYscore tmp:price 50 +INF> EVALSHA b81c2b... 1 tmp:name ice> ZINTERSTORE tmp:result tmp:price tmp:name> ZCOUNT tmp:result -INF +INF> ZRANGE tmp:result 0 100

我使用ZCOUNT调用预先知道我将拥有多少个结果页面,数量为/ 100.

正如我之前所说,这与Redis 3.2很好地配合.但是当我试图在AWS上运行代码时,它只支持Redis高达2.8,我无法再让它工作了.我不知道如何在不使用脚本或不从脚本编写的情况下使用HSCAN游标进行迭代.有一种方法可以在Redis 2.8上运行吗?

一些考虑:

>我知道我可以在Redis之外进行部分处理(比如迭代光标或交叉匹配),但它会影响应用程序的整体性能.
>我不想自己部署Redis实例来使用3.2版.
>上面的标准(价格范围和名称)只是一个简单的例子.我有其他领域和比赛类型,不仅仅是那些.
>我不确定我存储数据的方式是否是最佳方式.我愿意听取有关它的建议.

解决方法 问题不是你要写入数据库,而是你在HSCAN之后进行写 *** 作,这是一个非确定性的命令.

在我看来,很少有理由在Lua脚本中使用SCAN命令.该命令的主要目的是允许您以小批量执行 *** 作,这样您就不会锁定处理巨大密钥空间(或散列密钥空间)的服务器.由于脚本是原子的,因此使用HSCAN无济于事 – 您仍然会锁定服务器,直到整个过程完成.

以下是我可以看到的选项:

如果您不能冒险使用冗长的命令锁定服务器:

>在客户端上使用HSCAN.这是最安全的选择,但也是最慢的.

如果您想在单个原子Lua命令中进行尽可能多的处理:

>使用Redis 3.2和脚本效果复制.>在脚本中进行扫描,但将值返回给客户端并从那里开始写入. (也就是Karthikeyan Gopall的回答.)>而不是HSCAN,在脚本中执行HKEYS并使用Lua的模式匹配过滤结果.由于HKEYS是确定性的,因此后续写入不会有问题.当然,缺点是您必须首先读入所有键,无论它们是否与您的模式匹配. (虽然HSCAN也是散列大小的O(N).)

总结

以上是内存溢出为你收集整理的lua – 如何使用Redis将搜索文本与其他条件相结合?全部内容,希望文章能够帮你解决lua – 如何使用Redis将搜索文本与其他条件相结合?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1219732.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存