В целях обучения я пытаюсь написать простое структурированное хранилище документов в 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"
(опять же, только для моегоузнав, мне все равно, что я заново изобретаю колесо!) и это должно вернуть идентификаторы соответствующих документов (1234
в данном случае).Выражения AND
и OR
могут быть произвольно вложены.
Для каждого документа я генерирую ключи следующим образом
BOOK_TITLE.QUICK_BROWN_FOX = 1234
BOOK_YEAR.1999 = 1234
Я использую SADD чтобы сложить эти документы в серию наборов в форме KEYNAME.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 в качестве хранилища документов?