当前位置: 首页 > 面试题库 >

带Redis的多参数匹配器

牛兴安
2023-03-14
问题内容

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

有一组对象,每个对象都由一个字符串标识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将映射到以下插入:

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

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



 类似资料:
  • 问题内容: 如果满足以下条件,则需要创建一个与方法匹配的切入点的方面: 它用MyAnnotationForMethod注释 它的参数之一(可以有多个)用@MyAnnotationForParam注释(但也可以具有其他注释)。 方面类看起来像这样 注释方法 随着日食->警告:在poincut: 使用http://download.eclipse.org/tools/ajdt/35/update中的最

  • 我有一个包含id、volume和object_id列的表“signal”。 Blockquote嵌套异常为java.lang.IllegalArgumentException:参数值[1]与预期类型不匹配

  • 问题内容: 我希望能够将多个单词搜索与多个字段匹配,其中每个搜索的单词都包含在 任何 字段,任何组合中。问题是我想 避免使用 query_string。 我希望搜索“ John Smith”以仅匹配文档1。以下查询满足了我的需要,但我宁愿避免使用query_string,以防用户传递“ OR”,“ AND”和任何其他高级参数。 问题答案: 您正在寻找的是多重匹配查询,但是它的执行效果并不理想。 比

  • 问题内容: 我在和中遇到以下问题: 我调用以下javascript方法: 来自firebug的链接将如下所示: 根据以下链接: 错误:Sys.ParameterCountException:参数计数不匹配。 我设置 但我得到另一个错误 IE中不存在此问题。 编辑: 问题答案: 可能值得包装数据:用引号引起来的项目 变成

  • 我试图测试一个具有注入的RESTClient的Groovy类。 更新:我认为问题的核心是是false。如何断言两个闭包的相等性 我发现我可以在Spock中捕获闭包,从闭包构建XML,并比较XML对象。什么是一个简明和可读的方法来实现这一点?