Мы пытаемся создать приложение, которое возвращает постраничные результаты из cassandra db для пользовательского интерфейса.
Пользовательский интерфейс будет передавать fetchSize
и pagingState
нашему API, и на основании этого мы будем возвращать List<MyObject>
из size=fetchSize
. Если передано pagingState
, мы возобновим запрос с последней страницы (как упомянуто в документах cassandra: https://docs.datastax.com/en/developer/java-driver/3.6/manual/paging/)
Обратите внимание, что я использую драйвер Cassandra версии 3.6.
Но когда мы это реализовали, Cassandra всегда возвращает все записи в базе данных, игнорируя размер выборки, что, в свою очередь, приводит к значению null
для ResultSet.getExecutionInfo().getPagingState()
. Как мне это решить?
Я создал 16 записей в своей базе данных для MyObject
и попытался передать размер выборки как 5, чтобы получить их. Все 16 записей имеют одинаковый ключ раздела ID-1
.
// Util method to invoke Statement. "session" is cassandra session
public static ResultSet execute(int pageSize, Statement statement, String pageState) {
if (isVoid(pageSize)) {
pageSize=-1;
}
statement.setFetchSize(pageSize);
if (!isVoid(pageState)) {
statement.setPagingState(PagingState.fromString(pageState));
}
return session.execute(statement);
}
// Accesor interface method for my query that returns a Statement
object
@Query("SELECT * FROM " + MY_TABLE + " WHERE id=:id")
Statement getAll(@Param("id") String id);
// Main Code returning list of MyObject that has an object Mapper ->
//mapper
Statement statement=accessor.getAll("ID1");
ResultSet rs=execute(5,statement,null );
List<MyObject> list=mapper.map(rs).all();
String pageState=rs.getExecutionInfo().getPagingState();
В приведенном выше коде я ожидал, что Cassandra вернет список из 5 MyObject
объектов и будет иметь строковое значение для моей переменной pageState
.
Ни один из них не работал, как ожидалось.
Список имел размер 16 (в основном он выбирал все записи)
и из-за вышеизложенного, pageState
было null
, поскольку все записи уже были получены.
Что мне здесь не хватает?
EDIT:
Из наблюдения ResultSet
будет учитывать fetchSize, переданный в операторе, но когда мы сопоставим его с List<MyObject>
, используя метод all()
, он извлекает все результаты в базе данных (размера = широкий кластер fetchSize).
Поэтому, когда я вызывал Result#one
метод 5 (= pageSize
) раз и помещал их в список, я получил состояние подкачки, а также результаты размера страницы размера.
Пример метода Util для выше
public static <T> List<T> getPaginatedList(ResultSet resultSet, Mapper<T> mapper,int pageSize) {
List<T> entities=new ArrayList<>();
Result<T> result=mapper.map(resultSet);
IntStream.range(1,pageSize).forEach(i->{
entities.add(result.one());
});
return entities;
}
Как это отразится на производительности?