Кассандра: выберите только последние строки

Я работаю со следующей таблицей:

CREATE TABLE IF NOT EXISTS lp_registry.domain (
    ownerid text,
    name1st text,
    name2nd text,
    name3rd text,
    registrar text,
    registered timestamp,
    expiration timestamp,
    updated timestamp,
    technologies list<text>,
    techversions list<text>,
    ssl boolean,
    PRIMARY KEY (
        (name1st, name2nd, name3rd), 
        registrar, ownerid, registered, expiration, updated
    )
);

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

Я выполняю этот выбор:

SELECT * FROM lp_registry.domain WHERE 
    registrar = 'REG-WEDOS' AND 
    ownerid = 'FORPSI-JAF-S497436' 
ALLOW FILTERING;

Но в результате я хочу получить только строки с последним «обновленным» значением для каждого уникального «name3rd.name2nd.name1st».

Если бы я был в стандартной базе данных SQL, я бы использовал вложенный выбор с MAX или GROUP BY. Однако это не поддерживается Cassandra (MAX (), DISTINCT и group by in Кассандра). Но что мне делать в CQL?


person Michal    schedule 02.01.2016    source источник


Ответы (2)


Расширяя ответ Седрика (который является отличным советом и будет рассматривать его как ответ, который нужно принять), вы получите примерно структуру таблицы нравиться:

CREATE TABLE IF NOT EXISTS lp_registry.domain (
    ownerid text,
    name1st text,
    name2nd text,
    name3rd text,
    registrar text,
    registered timestamp,
    expiration timestamp,
    updated timestamp,
    technologies list<text>,
    techversions list<text>,
    ssl boolean,
    PRIMARY KEY ((registrar, ownerid), updated, name1st, name2nd, name3rd)
) WITH CLUSTERING ORDER BY (updated desc);

При выборе данных он будет возвращать строки с самыми последними updated значениями в разделе для запрашиваемого регистратора и владельца.

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

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

Все усложняется, если вы хотите получить самые последние обновленные из всех данных. Эту проблему нелегко решить с помощью cassandra, если только все не используют один и тот же раздел, который имеет свой собственный набор проблем (пример стратегии с использованием «фиктивного» раздела ключ).

person Andy Tolbert    schedule 02.01.2016
comment
Спасибо, Энди. Таким образом, невозможно сделать что-то подобное в cassandra stackoverflow.com/questions/22889722/? - person Michal; 03.01.2016
comment
Наверное, не без помещения всего в один раздел. В качестве альтернативы вы можете использовать что-то вроде SparkSQL с коннектором Spark cassandra, чтобы делать более гибкие запросы. - person Andy Tolbert; 03.01.2016

Необходимо изменить всю схему. SELECT, который вы делаете, очевидно важный с точки зрения вашего приложения, не требует ALLOW FILTERING: вы должны денормализовать свои данные и создать таблицу, где registrar и ownerid являются ключами раздела.

В этой денормализованной структуре updated должен быть ключом раздела, отсортированным с DESC. Тогда запрос будет

SELECT * FROM lp_registry.domain WHERE registrar='XXX' AND ownerid='YYY' LIMIT 10;

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

Ответ Энди содержит более подробную информацию и пример структуры вашей таблицы.

person Cedric H.    schedule 02.01.2016
comment
Большое спасибо за ваш ответ и совет. Извините за вопрос, но я не вижу трюка, который позволяет мне получать только последние строки для уникальных доменных имен. В примере будет выбрано 10 недавно обновленных доменов для данного регистратора и владельца. Но как мне добиться их уникального города? - person Michal; 02.01.2016
comment
@Michal Я не уверен, что понимаю ваш вопрос / комментарий, но я постараюсь обновить свой ответ сегодня же. - person Cedric H.; 02.01.2016