【问题标题】:Compound Queries with Redis使用 Redis 进行复合查询
【发布时间】:2011-04-18 13:17:34
【问题描述】:

出于学习目的,我正在尝试在 Redis 中编写一个简单的结构化文档存储。在我的示例应用程序中,我正在索引数百万个类似于以下内容的文档。

<book id="1234">
    <title>Quick Brown Fox</title>
    <year>1999</year>
    <isbn>309815</isbn>
    <author>Fred</author>
</book>

我正在编写一个小查询语言,它允许我说 YEAR = 1999 AND TITLE="Quick Brown Fox"(同样,只是为了我的学习,我不在乎我在重新发明轮子!)这应该返回匹配的 ID文档(在这种情况下为1234)。 ANDOR 表达式可以任意嵌套。

对于每个文档,我按如下方式生成密钥

BOOK_TITLE.QUICK_BROWN_FOX = 1234
BOOK_YEAR.1999 = 1234

我正在使用SADDKEYNAME.VALUE = { REFS } 的形式将这些文档放入一系列集合中。

当我进行查询时,我将表达式解析为 AST。诸如YEAR=1999 之类的简单表达式直接映射到SMEMBERS 命令,该命令让我返回匹配的文档集。但是,我不确定如何最有效地执行 AND 和 OR 部分。

给定一个查询,例如:

(TITLE=Dental Surgery OR TITLE=DIY Appendectomy)
    AND
(YEAR = 1999 AND AUTHOR = FOO)

我目前向 Redis 提出以下请求以回答这些查询。

-- Stage one generates the intermediate results and returns RANDOM_GENERATED_KEY3
SUNIONSTORE RANDOMLY_GENERATED_KEY1 BOOK_TITLE.DENTAL_SURGERY BOOK_TITLE.DIY_APPENDECTOMY
SINTERSTORE RANDOMLY_GENERATED_KEY2 BOOK_YEAR.1999 BOOK_YEAR.1998
SINTERSTORE RANDOMLY_GENERATED_KEY3 RANDOMLY_GENERATED_KEY1 RANDOMLY_GENERATED_KEY2

-- Retrieving the top level results just requires the last key generated
SMEMBERS RANDOMLY_GENERATED_KEY3

当我遇到AND 时,我会根据两个子键使用SINTERSTORE(同样对于OR,我使用SUNIONSTORE)。我随机生成一个密钥来存储结果(并设置一个短的 TTL,这样我就不会用垃圾填充 Redis)。在这一系列命令结束时,返回值是我可以使用SMEMBERS 检索结果的键。我使用存储功能的原因是我不想将所有匹配的文档引用传输回服务器,所以我使用临时键将结果存储在 Redis 实例上,然后只在结束。

我的问题很简单,这是将 Redis 用作文档存储的最佳方式吗?

【问题讨论】:

  • 我已经采用了这种方法,并且发现它非常快(与 Redis 相关的大多数事情一样)。您可以做的一件很酷的事情是缓存中间键以获取要缓存的查询片段(如下 Tom 所建议)。我还对 and 和 or 进行了一些优化,以避免在异常情况下存储中间键(例如,空集与 AND 和 OR 与整个文档集)。

标签: redis key-value


【解决方案1】:

我正在使用与排序集类似的方法来实现全文索引。总体方法很好,尽管您可以进行一些相当简单的改进。

  • 您可以使用查询(或其缩写形式)作为键,而不是使用随机生成的键。这样一来,您就可以重复使用已经计算过的集合,如果您在两个通常以相似方式组合的大型集合中进行查询,则可以显着提高性能。
  • 将标题作为一个完整的字符串处理将导致非常多的单个成员集。如果您确实需要,最好为标题中的单个单词编制索引并过滤最终结果以实现完全匹配。

【讨论】:

  • 谢谢!我曾考虑过重用密钥,希望这有助于查询片段缓存。标题作为一个完整的字符串很好,我将不得不考虑如何对这些进行匹配。
猜你喜欢
  • 2020-05-10
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 2017-02-16
  • 2011-04-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多