Временные ряды Cassandra: разрешить фильтрацию, сегменты или другое

Я знаю, что здесь есть много вопросов о временных рядах, но мой, похоже, не подходит для данных решений. Я также новичок в Cassandra, поэтому я могу подходить к этому с неправильным мышлением. Потерпите меня.

Я получаю данные поиска в виде:

datetime_searched, term_used, product_found

и запрос, который я хотел бы сделать:

Учитывая дату начала и дату окончания, вернуть все пары термин-продукт, попадающие в это временное окно. Первоначально окно будет длиной в месяц. Это может (читай: будет) измениться.

Например, при наличии следующих данных:

2013-11-20 00:00:00, "christmas", "decorated tree"
2014-12-01 20:00:00, "christmas", "wrapping paper"
2014-12-23 15:00:00, "christmas", "decorated tree" (duplicate term-product)

и запрос для временного диапазона с 2014-12-01 по 2015-01-01, я хотел бы иметь возможность получить:

"christmas", "wrapping paper"
"christmas", "decorated tree"

Мой первоначальный подход выглядел как большинство примеров для данных временных рядов:

CREATE TABLE search_terms (
  datetime_searched timestamp,
  term_used text,
  product_found text,
  PRIMARY KEY (term_used, date_searched)
);

SELECT term_used, product_found
FROM search_terms 
WHERE datetime_searched > [start] 
AND datetime_searched < [end];

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

Моя вторая идея состояла в том, чтобы создать сегменты времени, но это решение, похоже, работает, только если я ограничу запрос сегментами. Это также создает точки доступа — в моем первоначальном случае это точка доступа на месяц. Например, для ежедневных сегментов:

CREATE TABLE search_terms_by_day (
  datetime_searched timestamp,
  day_searched timestamp,
  term_used text,
  product_found text,
  PRIMARY KEY (day_searched)
);

SELECT term_used, product_found
FROM search_terms_by_day
WHERE day_searched=[my limited query's bucket];

Итак, каковы мои варианты? Ограничиваю ли я свои запросы размером корзины, возможно, создавая много CF с разными размерами корзины, и все это при создании хотспотов; я вынужден использовать вторичные индексы; или есть другой вариант, о котором я не знаю?

Заранее спасибо.


person Jake Greene    schedule 28.04.2015    source источник


Ответы (1)


Написание этого вопроса помогло мне разобраться с некоторыми из моих проблем. Я придумал альтернативное решение, которым я более-менее доволен, но оно потребует некоторой тонкой настройки.

Существует возможность вычислить все сегменты времени, к которым нам нужно получить доступ, сделав запрос для каждого из этих сегментов с фильтром, чтобы получить нужные нам записи.

CREATE TABLE search_terms_by_day_of_year (
  day_searched int, // 1 - 366
  datetime_searched timestamp,
  term_used text,
  product_found text,
  PRIMARY KEY (day_searched, datetime_searched, term_used, product_found)
);

// Make N of these, with a different day_searched
SELECT term_used, product_found
FROM search_terms_by_week
WHERE day_searched = 51
AND datetime_searched > [start]
AND datetime_searched < [end]

Плюсы:

  • Избегает сканирования всех данных поиска
  • Позволяет использовать меньшие интервалы времени, что, в свою очередь, уменьшает количество горячих точек.

Отрицательные:

  • Требуется логика для определения необходимых ключей раздела
  • Будет точка доступа для записи на период ведра (в приведенном выше примере один день)
  • Плохой выбор размера корзины по отношению к диапазону запроса потребует просмотра всех корзин, сводя на нет любые выгоды.
  • Несколько запросов к базе данных. Чем меньше ведро, тем больше вызовов требуется.

Пожалуйста, дайте мне знать, если есть лучшее решение для этого

person Jake Greene    schedule 28.04.2015
comment
Чтобы избежать проблемы со сканированием всех сегментов, вместо дня года можно использовать дату поиска. - person Jake Greene; 08.05.2015