Redis的多参数匹配查找器

时间:2011-10-29 14:03:13

标签: redis

我需要为某些数据集创建一个匹配查找器系统,如下所示:

有一组对象,每个对象都由字符串ObjectID标识。

每个对象都有N个属性P i 。每个属性值都是一个字符串。

N = 3的数据库示例(在现实生活中N = 8)。

ObjectID: P1     P2    P3
--------------------------------
APPLE:    RED    ROUND FRUIT
ORANGE:   ORANGE ROUND FRUIT
CARROT:   RED    LONG  VEGETABLE

系统必须返回ObjectID的集合,匹配对象属性的给定查询。在查询中,用户必须指定所有属性值。或者,对于查询中的部分或全部属性,用户可以指定“通配符”*,这意味着任何属性值都符合条件。

示例查询:

P1  P2    P3        => Result
------------------------------------
*   ROUND FRUIT     => APPLE, ORANGE
RED LONG  VEGETABLE => CARROT
RED *     *         => CARROT, APPLE

所有这些都是用SQL完成的。

问题是:有没有一种巧妙的方法可以用Redis做到这一点?

请注意,我对基于Redis的解决方案感兴趣,专门用于自我教育;对于这个特殊问题,其他数据库是非正式的。

更新:每个P i 和应用程序端过滤的明确ObjectID列表的简单解决方案对我来说看起来不够整洁: - )

1 个答案:

答案 0 :(得分:7)

你在这里要做的是倒排索引。

对于每列,让它映射到“set”。然后,您可以将这些集相交以获得结果。

因此,APPLE: RED ROUND FRUIT将映射到以下插入内容:

SADD p1:RED APPLE
SADD p2:ROUND APPLE
SADD p3:FRUIT APPLE

然后,假设我要查询* ROUND FRUIT,我会这样做:

SINTER p2:ROUND p3:FRUIT

此命令采用p2:ROUND集和p3:FRUIT集中的项目的交集。这将返回ROUNDFRUIT的所有项目,而不是关注p1的内容。

其他一些例子:

SMEMBERS p1:GREEN
SINTER p1:RED p2:ROUND p3:FRUIT
SUNION p1:RED p1:GREEN

我的上述答案将使用一些计算能力,因为交叉操作是O(N*M)。这是一种更加占用内存的方法,但会有更快的检索速度,因为它有效地预先计算了索引。

对于每个属性组合,请创建一个存储集合的键:

因此,APPLE: RED ROUND FRUIT将映射到以下插入内容:

SADD RED:ROUND:FRUIT APPLE
SADD :ROUND:FRUIT APPLE
SADD RED::FRUIT APPLE
SADD RED:ROUND: APPLE
SADD RED:: APPLE
SADD :ROUND: APPLE
SADD ::FRUIT APPLE
SADD ::: APPLE

然后,要查询,只需访问相应的密钥即可。例如,* ROUND FRUIT只是

SMEMBERS :ROUND:FRUIT

显然,当你有很多维度时,这在内存方面根本不能很好地扩展,但是检索结果会非常敏捷。