Только диапазон дат сканирования временной метки Cassandra CQL

У меня есть таблица, как показано ниже.

CREATE TEST(
 HOURLYTIME TIMESTAMP,
 FULLTIME TIMESTAMP,
 DATA TEXT,
 PRIMARY KEY(HOURLYTIME,FULLTIME)
)

Я вставил запись (2014-12-12 00:00:00,2014-12-12 00:00:01,'Hello World')

Я хотел бы искать на основе диапазона даты и времени в поле HOURLYTIME, которое содержит почасовые записи. Когда я пытался использовать token(), например

select * from TEST where token(HOURLYTIME)=token('2014-12-12')

чтобы получить все записи на эту дату, он возвращает только одну часовую запись, т.е. для

 2014-12-12 **00:00:00**

Если я добавлю диапазон дат

select * from TEST where token(HOURLYTIME)>=token('2014-12-12') AND token(HOURLYTIME)<=token('2014-12-14');

Выдает ошибку: Для начальной границы найдено более одного ограничения.

Как решить эту проблему.

Я могу сканировать, используя FULLTIME, но мне нужно предоставить ALLOW FILTERING, который будет сканировать целые записи и неэффективно.


person Anil    schedule 14.01.2015    source источник
comment
можно попробовать › 2014-12-12 00:00:00 & ‹ 2014-12-12 23:59:59 ...   -  person Helping Hand..    schedule 14.01.2015


Ответы (3)


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

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

person RussS    schedule 14.01.2015

Чтобы делать запросы диапазона, вам нужно иметь этот столбец в качестве столбца кластеризации.

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

Итак, в качестве примера, где я использую device_id в качестве ключа раздела:

CREATE TABLE IF NOT EXISTS mykeyspace.device_data (
 DEVICE_ID text,
 HOURLYTIME TIMESTAMP,
 FULLTIME TIMESTAMP,
 DATA TEXT,
 PRIMARY KEY (DEVICE_ID, HOURLYTIME, FULLTIME)
);

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');

INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');

-- Effective range query
SELECT * FROM mykeyspace.device_data
WHERE device_id = 'Spam machine'
    AND hourlytime > '2014-12-12 00:00:00'
    AND hourlytime < '2014-12-12 00:02:00';

Или другой пример, где я разбиваю данные по дням (что приведет к хорошему распределению данных по кластеру) и выполняю запросы диапазона:

CREATE TABLE IF NOT EXISTS mykeyspace.day_data (
     DAYTIME timestamp,
     HOURLYTIME TIMESTAMP,
     FULLTIME TIMESTAMP,
     DATA TEXT,
     PRIMARY KEY (DAYTIME, HOURLYTIME, FULLTIME)
);

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');

INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');

SELECT * FROM mykeyspace.day_data
WHERE daytime = '2014-12-12'
    AND hourlytime > '2014-12-12 00:00:00'
    AND hourlytime < '2014-12-12 00:02:00';

На PlanetCassandra есть очень полезная статья о данных временных рядов.

person Raman Yelianevich    schedule 14.01.2015

Запрос диапазона дат работает нормально. Я использую следующие версии

[cqlsh 4.1.0 | Cassandra 2.0.4 | CQL spec 3.1.1 | Thrift protocol 19.39.0]

Проблема может быть в старых версиях. Пожалуйста, проверьте.

person karthik manchala    schedule 14.01.2015