2016-11-30 6 views
1

У меня есть следующие таблицы для хранения данных временных рядов:Cassandra datamodelling

CREATE TABLE alerts_by_year_day (
    day_of_year int, 
    year int, 
    alert_timestamp timestamp, 
    serial_number text, 
    alert_id uuid, 
    alert_type text, 
    .... 
    .... 
    PRIMARY KEY((year, day_of_year), alert_timestamp, serial_number, alert_id) 
) WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC); 
  1. Для отчета пользовательского интерфейса Я хочу, чтобы получить все оповещения на определенный период времени. У меня есть этот запрос:

выберите * из alerts_by_year_day где год = 2015 и day_of_year в (241, 240);

Но этот запрос возвращает мне результаты, которые находятся в порядке ASC года, а затем в порядке ASC дня. Результаты аналогичные

2015 | 240 | .....

2015 | 241 | .....

Но я хочу показывать последние результаты сначала или в порядке убывания. Добавление 'order by alert_timestamp;' дает ошибку Итак, как я могу отображать результаты, которые находятся в порядке убывания?

  1. Затем в течение определенного периода времени я хочу получить только определенные типы предупреждений на основе alert_type.

Так что я создал вид мат, как это:

CREATE MATERIALIZED VIEW alerts_by_type_and_timestamp AS 
    SELECT * 
    FROM alerts_by_year_day 
    WHERE alert_timestamp IS NOT NULL AND 
     alert_type IS NOT NULL AND 
     day_of_year IS NOT NULL AND 
     year IS NOT NULL AND serial_number IS NOT NULL AND 
     alert_id IS NOT NULL 
    PRIMARY KEY ((year, day_of_year, alert_type), alert_timestamp, serial_number, alert_id) 
    WITH CLUSTERING ORDER BY (alert_timestamp DESC, serial_number DESC, alert_id DESC); 

Но, конечно, он возвращает результаты по типу первого и в том, что с помощью временной метки. Я ищу только подмножество типов и в порядке desc, в котором они были сгенерированы. Возможно ли это в Кассандре?

Благодаря

ответ

1

Порядок разделов в лексемы порядке. Его порядок хеша murmur3 первичного ключа. то есть:

cqlsh:test> select * from alerts_by_year_day ; 

year | day_of_year | alert_timestamp     | serial_number | alert_id        | alert_type 
------+-------------+---------------------------------+---------------+--------------------------------------+------------ 
2015 |   10 | 1970-01-01 00:00:00.001000+0000 |   s123 | b7baa710-b87b-11e6-9137-eb2177fd2cc2 |  type 
2015 |   110 | 1970-01-01 00:00:00.001000+0000 |   s123 | bf110270-b87b-11e6-9137-eb2177fd2cc2 |  type 
2015 |   11 | 1970-01-01 00:00:00.001000+0000 |   s123 | bce08de1-b87b-11e6-9137-eb2177fd2cc2 |  type 
2016 |   110 | 1970-01-01 00:00:00.001000+0000 |   s123 | c2e22eb1-b87b-11e6-9137-eb2177fd2cc2 |  type 

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

Это требует нескольких выборок на каждое значение в предложении in и может стать неэффективным быстро, если вы слишком много вложите в него, так как это накладывает большую нагрузку на вашего координатора. Он стоит почти так же, как и два раза asyncselect запросов. Который вы тогда можете прочитать в том порядке, в котором вы хотите. Это также избавляет вас от того, чтобы один координатор в вашем кластере управлял выборами на многих узлах, в конечном счете это может помочь в сохранении кластера. 1 запрос в день - это совсем не плохо для повторения в вашем приложении.

Если дни не являются «повседневными», может потребоваться рассмотреть вторую таблицу, которая только (year, day_of_year) и (type, year, day_of_year), которую вы пишете, когда вы делаете свою вставку, прежде чем выполнять свой запрос.

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

year = 2015 
days = query('select * from alert_day_index where year = %s', year) 
results = [] 
for day in days: 
    results.extend(query('select * from alerts_by_year_day where year = %s and day_of_year = %s', year, day)) 

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

+0

Спасибо за ответ! Очень сложно запускать запросы на каждый день, а затем также хранить подробные сведения о папках для дней, которые отображаются и т. Д. – user1860447