使用Redis进行复合查询

使用Redis进行复合查询,redis,key-value,Redis,Key Value,出于学习目的,我正在尝试在Redis中编写一个简单的结构化文档存储。在我的示例应用程序中,我索引了数百万个看起来有点像下面这样的文档 <book id="1234"> <title>Quick Brown Fox</title> <year>1999</year> <isbn>309815</isbn> <author>Fred</author> </

出于学习目的,我正在尝试在Redis中编写一个简单的结构化文档存储。在我的示例应用程序中,我索引了数百万个看起来有点像下面这样的文档

<book id="1234">
    <title>Quick Brown Fox</title>
    <year>1999</year>
    <isbn>309815</isbn>
    <author>Fred</author>
</book>
我正在使用以
KEYNAME.VALUE={REFS}
的形式将这些文档打包成一系列集合

当我进行查询时,我将表达式解析为AST。一个简单的表达式,如
YEAR=1999
直接映射到一个命令,该命令将返回匹配文档集。但是,我不确定如何最有效地执行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
当我遇到
时,我会根据两个子键使用(对于
我也会使用类似的键)。我随机生成一个键来存储结果(并设置一个短TTL,这样我就不会用cruft填充Redis)。在这一系列命令结束时,返回值是一个键,我可以使用它来检索结果。我使用store函数的原因是我不想将所有匹配的文档引用传输回服务器,所以我使用临时键将结果存储在Redis实例上,然后在最后只返回匹配的结果


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

我正在对排序集使用类似的方法来实现全文索引。总体方法是好的,不过您可以做一些相当简单的改进

  • 您可以使用查询(或其简短形式)作为密钥,而不是使用随机生成的密钥。这使您可以重用已经计算过的集合,如果您在两个通常以类似方式组合的大型集合之间进行查询,则可以显著提高性能
  • 将标题作为完整字符串处理将导致大量的单成员集。如果你真的需要,最好为标题中的单个单词编制索引,并过滤最终结果以获得精确匹配

谢谢!我曾考虑过重用这些键,希望这对查询片段缓存有所帮助。作为一个完整的字符串,标题的要点很好,我必须考虑如何在这些字符串上进行匹配。我采用了这种方法,我发现它速度惊人(与大多数与Redis相关的东西一样)。您可以做的一件很酷的事情是缓存中间键,以获取要缓存的查询片段(如下面Tom所建议的)。我还对and和or进行了一些优化,以避免在病理情况下存储中间密钥(例如,使用and和or整个文档集的空集)。
-- 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