我需要为某些数据集创建一个匹配查找器系统,如下所示:
有一组对象,每个对象都由一个字符串标识ObjectID。
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和应用程序端过滤具有显式列表的简单解决方案对我来说似乎不够整洁:-)
您要在此处执行的操作是倒排索引。
对于每一列,将其映射到“集合”。然后,您可以将这些集合相交以获得结果。
因此,APPLE: RED ROUND FRUIT将映射到以下插入:
APPLE: RED ROUND FRUIT
SADD p1:RED APPLE SADD p2:ROUND APPLE SADD p3:FRUIT APPLE
然后,假设我要查询* ROUND FRUIT,我会这样做:
* ROUND FRUIT
SINTER p2:ROUND p3:FRUIT
此命令获取p2:ROUND集合和p3:FRUIT集合中项目的交集。这将返回所有的项目ROUND和FRUIT,不关心什么p1是。
p2:ROUND
p3:FRUIT
ROUND
FRUIT
p1
其他一些例子:
SMEMBERS p1:GREEN SINTER p1:RED p2:ROUND p3:FRUIT SUNION p1:RED p1:GREEN
我的上述答案将使用某种计算能力,因为相交操作为O(N*M)。这是一种占用大量内存的方法,但由于它可以有效地预先计算索引,因此检索速度更快。
O(N*M)
对于每种属性组合,创建一个存储一组的键:
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
显然,当您有很多尺寸时,这在内存方面根本无法很好地扩展,但是检索结果将非常快捷。