小编典典

带Redis的多参数匹配器

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

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

查询示例:

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

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

问题是:使用Redis可以做到这一点吗?

请注意 ,出于自学目的,我特别对 基于Redis的 解决方案感兴趣;其他DB则无法解决该特定问题。

更新:ObjectID对于每个P i和应用程序端过滤具有显式列表的简单解决方案对我来说似乎不够整洁:-)


阅读 299

收藏
2020-06-20

共1个答案

小编典典

您要在此处执行的操作是倒排索引。

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

因此,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

显然,当您有很多尺寸时,这在内存方面根本无法很好地扩展,但是检索结果将非常快捷。

2020-06-20