#cassandra #pagination
#cassandra #разбивка на страницы
Вопрос:
Я следовал инструкциям на официальном веб-сайте cassandra, чтобы асинхронно использовать результирующие наборы моих запросов.
ResultSetFuture future = session.executeAsync("SELECT release_version FROM system.local");
Futures.addCallback(future,
new FutureCallback<ResultSet>() {
@Override public void onSuccess(ResultSet result) {
gui.setMessage("Cassandra version is " result.one().getString("release_version"));
}
@Override public void onFailure(Throwable t) {
gui.setMessage("Error while reading Cassandra version: " t.getMessage());
}
},
MoreExecutors.sameThreadExecutor()
);
В основном это работает нормально, но для того, чтобы увидеть, сколько строк было извлечено, я обернул свой FutureCallback в LogAwareCallback, который, немного упрощенный, выглядит следующим образом:
private static final class LogAwareCallback implements FutureCallback<ResultSet> {
private final FutureCallback<ResultSet> origin;
private final String query;
private final Object [] parameters;
private LogAwareCallback(
FutureCallback<ResultSet> origin,
String query,
Object [] parameters) {
this.origin = origin;
this.query = query;
this.parameters = parameters;
}
@Override
public void onSuccess(ResultSet rows) {
origin.onSuccess(rows);
// as all rows should have been processed at this state,
// it should be safe to call all with size now
int resultSize = rows.all().size();
log(query, parameters, resultSize);
}
@Override
public void onFailure(Throwable throwable) {
// FAILURE HANDLING...
}
private void log(String query, Object [] parameters, int resultSize) {
// LOG result size for given query
}
}
Проблема в том, что обернутый FutureCallback уже использовал весь результирующий набор на данный момент времени, и я всегда получаю размер результата 0, хотя было обработано несколько строк.
Таким образом, мой вопрос в том, есть ли способ получить количество возвращенных строк из результирующего набора, даже если оно было полностью использовано?
Ответ №1:
all() возвращает оставшиеся строки и очищает список. Таким образом, вы не сможете легко получить количество обработанных строк. Но есть и альтернатива,
Если вы изменили свой onSuccess в LogAwareCallback на,
@Override
public void onSuccess(ResultSet rows) {
*int resultSize = rows.getAvailableWithoutFetching();*
log(query, parameters, resultSize);
origin.onSuccess(rows);
}
вы получите количество строк в результирующем наборе без извлечения дополнительных строк из базы данных. Здесь есть оговорка, что если общее количество строк, ожидаемое в результате запроса, больше размера страницы, вы получите только это (размер страницы) в качестве выходных данных.
Комментарии:
1. Я тоже пробовал это, но это также дало мне 0 ResultSize.
2. вы пробовали это перед вызовом origin.onSuccess(rows); и он все равно дал вам 0? А затем он также напечатал «Версия Cassandra» …?
3. аааа, понятно. Извините, не понял, что вы меняете порядок операторов. Я предполагаю, что getAvailableWithoutFetching — довольно легкая операция?
4. да, я бы так подумал, поскольку он также часто используется при ранней выборке во время разбивки на страницы. Но поскольку я не знаю внутреннего кода драйвера, возможно, вам захочется провести тест перед использованием в производственном коде.
5. вызов O (1). Довольно производительный. Это решило вашу проблему? Спасибо.