出于学习目的,我尝试在 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
在这种情况下)。这AND
and OR
表达式可以任意嵌套。
对于每个文档,我生成密钥如下
BOOK_TITLE.QUICK_BROWN_FOX = 1234
BOOK_YEAR.1999 = 1234
我在用着SADD http://redis.io/commands/sadd将这些文档放入以下形式的一系列集合中KEYNAME.VALUE = { REFS }
.
当我进行查询时,我将表达式解析为 AST。一个简单的表达式,例如YEAR=1999
直接映射到SMEMBERS http://redis.io/commands/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
I use 辛特商店 http://redis.io/commands/sinterstore基于两个子键(类似地OR
I use 新联商城 http://redis.io/commands/sunionstore)。我随机生成一个密钥来存储结果(并设置一个短的 TTL,这样我就不会在 Redis 中填满垃圾)。在这一系列命令结束时,返回值是一个键,我可以用它来检索结果SMEMBERS http://redis.io/commands/smembers。我使用存储功能的原因是我不想将所有匹配的文档引用传输回服务器,因此我使用临时密钥将结果存储在 Redis 实例上,然后仅在以下位置返回匹配结果结束。
我的问题很简单,这是使用 Redis 作为文档存储的最佳方式吗?