Итерация через широкую строку Cassandra с CQL3

Как я могу потянуть в диапазон столбцов Composite с CQL3?

Рассмотрим следующее:

CREATE TABLE Stuff (
    a int,
    b text,
    c text,
    d text,
    PRIMARY KEY (a,b,c)
);

В Cassandra то, что это эффективно делает, создает ColumnFamily с целыми строками (значениями a) и с CompositeColumns, состоящими из значений b и c и литеральной строки 'd'. Конечно, все это покрывается CQL3, поэтому мы подумаем, что мы вставляем в отдельные строки базы данных... но я отвлекаюсь.

И рассмотрим следующий набор входов:

INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','P','whatever0');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','Q','whatever1');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','R','whatever2');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','S','whatever3');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'A','T','whatever4');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','P','whatever5');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','Q','whatever6');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','R','whatever7');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','S','whatever8');
INSERT INTO Stuff (a,b,c,d) VALUES (1,'B','T','whatever9');

В моем текущем случае использования я хочу читать все значения Stuff, n за раз. Как мне это сделать? Здесь мой текущий прием с использованием n=4:

SELECT * FROM Stuff WHERE a=1 LIMIT 4;

И как и ожидалось, я получаю:

 a | b | c | d
---+---+---+-----------
 1 | A | P | whatever0
 1 | A | Q | whatever1
 1 | A | R | whatever2
 1 | A | S | whatever3

Проблема, с которой я сталкиваюсь, - это как я могу получить следующие 4? Вот моя попытка:

SELECT * FROM Stuff WHERE a=1 AND b='A' AND c>'S' LIMIT 4;

Это не работает, потому что мы ограничили b равным "A" - это разумная вещь! Но я ничего не нашел в синтаксисе CQL3, который позволяет мне продолжать итерацию в любом случае. Хотел бы я сделать что-то вроде:

SELECT * FROM Stuff WHERE a=1 AND {b,c} > {'A','S'} LIMIT 4;

Как достичь желаемого результата. А именно, как мне вернуть CQL3:

 a | b | c | d
---+---+---+-----------
 1 | A | T | whatever0
 1 | B | P | whatever1
 1 | B | Q | whatever2
 1 | B | R | whatever3

Ответ 2

После чтения документа CQL3 я не нашел способ добиться желаемого эффекта.

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

SELECT * FROM a = 1 LIMIT 4;

Однако нет способа получить следующие 4 в одном запросе. Но я могу сделать это кусочно. Последний элемент из указанного запроса -

 a | b | c | d
---+---+---+-----------
 1 | A | S | whatever3

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

SELECT * FROM a = 1 WHERE b = 'A' и c > 'S' LIMIT 4;

И в этом случае я получу одну строку CQL3:

 a | b | c | d
---+---+---+-----------
 1 | A | T | whatever4

(Теперь, если бы я получил 4 строки, я бы ударил предел, и я снова начал бы в следующий раз с последним элементом этого набора. Но сейчас у меня только одна строка.) Итак, чтобы получить остальное Я повторяю эту точку и получаю оставшиеся 3 строки:

SELECT * FROM a = 1 WHERE b > 'A' LIMIT 3;

И я продолжаю этот же алгоритм, пока я не пошагово сканирую, насколько мне нравится.

В приведенном выше примере PRIMARY KEY состоит из 3-х элементов, что означает, что под CQL в Cassandra имена столбцов представляют собой CompositeColumns из 2-х элементов (... ну в принципе, но разница здесь не имеет значения). И поскольку CompositeColumns состоят из двух элементов, вам нужно сделать 2 запроса, как я показал здесь. В общем случае, если PRIMARY KEY имеет элементы n, тогда вам нужно будет сделать запросы n-1, чтобы подделать проверку таблицы CQL (строка a.k.a Cassandra).


Обновление: действительно, на CQL3 нет курсора на стороне сервера (см. раздел "разбиение на страницы CQL3" здесь), и если вы хотел подделать его, вам придется использовать что-то, описанное выше (читайте дальше по этой ссылке, так что см. мою основную идею, разработанную автором сообщения).

Однако существует проблема JIRA относительно курсора на стороне сервера, который будет доступен в Cassandra 2 и который уже присутствует в Cassandra 2 Beta.

Существует также связанная с этим проблема JIRA, которая значительно облегчила бы реализацию курсора на стороне клиента, как я намекал выше. Но он остается нерешенным.


Update2: Проблема JIRA теперь исправлена.

Теперь вы можете запросить использование синтаксиса кортежа/вектора WHERE (c1, c2) > (1, 0)

Ответ 3

Что вы пытаетесь сделать, так это получить материал для разбивки на страницы в Кассандре. CQL3 не поддерживает это. Вы должны создать столбец, подходящий для сравнения, т.е. Меньше, чем операции, и этот столбец должен формировать возрастающую/уменьшающуюся последовательность. В самом деле, как заметило выше jorgebg, конкатенация b + c соответствовала бы этому.

Ответ 4

select * from stuff where a = 1 and (b,c) > ('A','S') limit 4;