如何将此SQL构建到redis数据库

时间:2017-01-16 02:22:34

标签: ruby database redis one-to-many

我在理解如何将此SQL数据库转换为redis数据库时遇到了一些麻烦。它是一对多的数据库,由关键字,响应和关联表组成,用于链接两者。

在关键字表格中我有:

|ID---Keyword|
 1    This
 2    Cool

在回复表中,我有

|ID---Response|
 1    "I agree"
 2    "wow"

在相关表中我有:

|ResponseID---KeywordID|
 1            1
 1            2
 2            2

要尝试在redis中解决此问题,我尝试使用普通字符串为关键字创建关键字ID的索引:

set keyword:1 This
set keyword:2 Cool

与回复相同:

set response:1 "I agree"
set response:2 "wow"

然后我用套装加入两个:

sadd keyword:1:response 1
sadd keyword:2:response 1
sadd keyword:2:response 2

现在我遇到的问题是如何轮询数据,就像我在SQL数据库上一样。我不确定这个问题是否是因为缺少信息被添加到redis数据库中,或者我是否缺乏经验。

基本上我想从我的软件中获取一组关键字,例如:“This”,“Cool”,然后查找他们的ID(分别为1和2)。然后从他们的ID使用相关索引来查找响应ID,然后使用响应ID来获取响应字符串。请注意,我需要首先获得与大多数关键字匹配的数据返回响应,因此,如果给出“此”,“酷”,则会显示“我同意”的响应,但如果仅给出关键字“酷”哇“和”我同意“将被收回。

这样做的目的是,当指定更多关键字时,响应将更具体地针对这些关键字。关键词越少,一般回复的可能性就越大。这可以在上面看到,当指定两个关键字时,只有一个响应,而当指定一个关键字时,有两个。 如果我可以根据匹配的匹配项最匹配的关键字对这些结果进行排序,也会有所帮助。

在redis DB中有足够的数据来解决这个问题吗?或者更多的是在访问redis数据库的客户端应用程序中完成。

我将通过ruby访问redis数据库,但如果需要显示任何代码示例,我可以使用任何语言并将其移植。

1 个答案:

答案 0 :(得分:0)

一种可能的解决方案是将关键字映射到redis响应集。

keyword1 => { response1, response2 }
keyword2 => { response1, response 3 }

您从软件中获取关键字,响应ID,然后使用此结构解决响应字符串的过程。添加回复后,您会将其添加到相应的关键字中。

您可以使用SCARD获取一组中的响应数。我个人没有看到一个更简单的结构,在给定关键字列表的情况下为您提供最多匹配的关键字。

使用集合的一个可能有用的改进是获得响应列表,以便您可以将关键字mapt存储到redis响应ID集。这将涉及一个额外的步骤,以使用响应ID从redis检索实际响应。

keyword1 => { 0, 1 }
keyword2 => { 0, 2 }
responses => [ response1, response2, response3]

其他想法

您还询问了redis数据库中是否有足够的数据来实现这一目标。鉴于上述结构,数据存在,但您需要决定在给定关键字列表的情况下如何/在何处计算响应计数。您可以编写一个lua脚本来返回一个排序列表,其中包含将在redis客户端上执行的匹配最多或最少的关键字。您还可以接收redis集并从ruby中计算该信息。

您应该查看集合的redis doc:

Redis Sets

如果要查找许多关键字之间的响应重叠,SINTER命令可能会派上用场。

更新

我认为最简单的方法是将所有响应放在lua中的一个大表中,然后返回响应表及其计数。 E.x:

k1 => r1, r2, r3
k2 => r1, r2
k3 => r1, r3

在这种情况下,我们最终会返回:

r1: 3
r2: 2
r3: 2

然后,您可以使用该表来确定如何继续处理结果。一些lua sudo代码如下:

local allResponses = {}

-- go over the keys and add their responses to the global response table
for keyIndex, keyword in ipairs(KEYS) do
    local responses = redis.call('smembers', keyword);
    allResponses.add(responses)
end

local counts = {}
for responseIndex, response in ipairs(allResponses) do
    counts[response] = counts[response] + 1
end

return counts