Как реализовать пагинацию для Кассандры с помощью клавиш? - PullRequest
0 голосов
/ 07 ноября 2018

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

CREATE TABLE sample (
    some_pk int,
    some_id int,
    name1 txt,
    name2 text,
    value text,
    PRIMARY KEY (some_pk, some_id, name1, name2)
)
WITH CLUSTERING ORDER BY(some_id DESC)

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

+---------+---------+-------+-------+-------+
| sample_pk| some_id | name1 | name2 | value |
+---------+---------+-------+-------+-------+
| 1       | 125     | x     | ''    | ''    |
+---------+---------+-------+-------+-------+
| 1       | 124     | a     | ''    | ''    |
+---------+---------+-------+-------+-------+
| 1       | 124     | b     | ''    | ''    |
+---------+---------+-------+-------+-------+
| 1       | 123     | y     | ''    | ''    |
+---------+---------+-------+-------+-------+

(для простоты я оставил некоторые столбцы пустыми. Ключ раздела (sample_pk) не важен)

давайте предположим, что размер моей страницы равен 2.

select * from sample where sample_pk=1 limit 2;

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

этот запрос не работает из-за ограничения одного отношения не-EQ

select * from where sample_pk=1 and some_id <= 124 and name1>='a' and name2>='' limit 2; 

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

select * from where sample_pk=1 and (some_id, name1, name2) <= (124, 'a', '') limit 2; 

Так что я застрял. Как я могу реализовать нумерацию страниц?

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

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

public Response getFromCassandra(Integer itemsPerPage, String pageIndex) {
    Response response = new Response();
    String query = "select * from sample where sample_pk=1";
    Statement statement = new SimpleStatement(query).setFetchSize(itemsPerPage); // set the number of items we want per page (fetch size)
    // imagine page '0' indicates the first page, so if pageIndex = '0' then there is no paging state
    if (!pageIndex.equals("0")) {
        statement.setPagingState(PagingState.fromString(pageIndex));
    }
    ResultSet rows = session.execute(statement); // execute the query
    Integer numberOfRows = rows.getAvailableWithoutFetching(); // this should get only number of rows = fetchSize (itemsPerPage)
    Iterator<Row> iterator = rows.iterator();
    while (numberOfRows-- != 0) {
        response.getRows.add(iterator.next());
    }
    PagingState pagingState = rows.getExecutionInfo().getPagingState();
    if(pagingState != null) { // there is still remaining pages
        response.setNextPageIndex(pagingState.toString());
    }
    return response;
}

обратите внимание, что если вы делаете цикл while, как показано ниже:

while(iterator.hasNext()) {
    response.getRows.add(iterator.next());
}

сначала будет выбрано число строк, равное размеру выборки, который мы установили, затем, пока запрос все еще совпадает с некоторыми строками в Cassandra, он будет извлекать снова из Cassandra до тех пор, пока не получит все строки, соответствующие запросу из Cassandra, что может не предназначен, если вы хотите реализовать функцию нумерации страниц

источник: https://docs.datastax.com/en/developer/java-driver/3.2/manual/paging/

0 голосов
/ 07 ноября 2018

Вы можете запустить свой второй запрос, как,

select * from sample where some_pk =1 and some_id <= 124 limit x;

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

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

...