Cassandra-SelectQuery-получить первую запись каждой минуты на основе второй - PullRequest
1 голос
/ 29 марта 2020

Может кто-нибудь сказать мне, как написать запрос выбора, чтобы возвращать первую запись каждой минуты? Первая запись здесь относится к первой записи каждой минуты (в секундах). Пожалуйста, смотрите пример ниже. Моя система будет регулярно получать данные каждые 5 секунд с устройства. Моя таблица будет выглядеть следующим образом.

CREATE TABLE device (
    deviceId text,
    datetime timestamp,
    temp float,
    volt float,
    PRIMARY KEY (deviceId, datetime)
) WITH CLUSTERING ORDER BY (datetime DESC);

Можно ли извлечь дату-время в запросе выбора, обработать его и найти первую запись каждой минуты?

insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:10:00+0000',0.12,6.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:10:05+0000',3.12,61.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:10:10+0000',2.12,16.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:10:15+0000',1.12,26.7);

insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:11:20+0000',4.12,11.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:11:25+0000',5.12,12.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:11:30+0000',6.12,23.7);
insert into device (deviceId,datetime,temp,volt)
values ('device123','2018-10-10 5:11:35+0000',7.12,126.7);

Мой запрос должен дать мне такой результат:

  • В течение 10-й минуты секунда = 00 темп = 0,12, вольт = 6,7
  • В течение 11-й минуты секунда = 20 темп = 4,12, вольт = 11,7

Можете ли вы дать советы о том, как я могу достичь этого в Кассандре?

1 Ответ

1 голос
/ 30 марта 2020

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

Или вы можете построить таблицу для partition данных за минуту. В этом случае вам потребуется добавить еще один ключ раздела в вашу таблицу, minute_bucket. Кроме того, чтобы откатить «первую» (или самую раннюю) строку в минуту, измените направление сортировки на клавише кластеризации datetime на возрастание (ASC). Пример:

CREATE TABLE device_by_minute (
    deviceId text,
    datetime timestamp,
    minute_bucket text,
    temp float,
    volt float,
    PRIMARY KEY ((deviceId, minute_bucket), datetime)
) WITH CLUSTERING ORDER BY (datetime ASC);

Затем (после загрузки данных) выполните многоключевой запрос, используя предложение PER PARTITION LIMIT, например:

aploetz@cqlsh:stackoverflow> SELECT * FROM device_by_minute
    WHERE deviceid='device123'
      AND minute_bucket IN ('2018-10-10 05:10','2018-10-10 05:11')
    PER PARTITION LIMIT 1;

 deviceid  | minute_bucket    | datetime                        | temp | volt
-----------+------------------+---------------------------------+------+------
 device123 | 2018-10-10 05:10 | 2018-10-10 05:10:00.000000+0000 | 0.12 |  6.7
 device123 | 2018-10-10 05:11 | 2018-10-10 05:11:20.000000+0000 | 4.12 | 11.7

(2 rows)

Примечания:

  • Многоключевые запросы, подобные этому, с использованием предложения IN в части ключа разделения не позволят Cassandra выяснить, какой узел содержит данные во время запроса. Затем он назначит «узел-координатор» для обработки компиляции набора результатов, а также для связи с узлами, содержащими запрошенные реплики. Относительно запроса по полному ключу раздела, это также не будет работать .
  • Этот запрос можно упростить, запустив SELECT * FROM device_by_minute PER PARTITION LIMIT 1;. Однако производительность запросов будет ухудшаться по мере роста набора данных. Еще лучше ограничить потенциальный набор результатов в предложении WHERE.
  • Я хотел бы, чтобы числовые элементы в предложении IN содержали только однозначные цифры.
...