Сложные Запросы с Redis - PullRequest
       21

Сложные Запросы с Redis

4 голосов
/ 17 апреля 2011

В целях обучения я пытаюсь написать простое структурированное хранилище документов в 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 в качестве хранилища документов?

1 Ответ

2 голосов
/ 18 апреля 2011

Я использую аналогичный подход с отсортированными наборами для реализации полнотекстовой индексации.Общий подход хорош, хотя есть несколько довольно простых улучшений, которые вы могли бы сделать.

  • Вместо того, чтобы использовать случайно сгенерированные ключи, вы можете использовать запрос (или его краткую форму) в качестве ключа,Это позволяет повторно использовать уже рассчитанные наборы, что может значительно повысить производительность, если у вас есть запросы к двум большим наборам, которые обычно объединяются одинаковыми способами.
  • Обработка заголовка как полной строки приведет к оченьбольшое количество наборов из одного члена.Может быть лучше проиндексировать отдельные слова в заголовке и отфильтровать окончательные результаты для точного соответствия, если вам это действительно нужно.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...