【发布时间】:2019-10-27 20:45:12
【问题描述】:
我们正在尝试创建一个从 cassandra db 为 UI 返回分页结果的应用程序。
UI 会将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()。我该如何解决?
我在我的数据库中为 MyObject 创建了 16 条记录,并尝试将 fetch size 传递为 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,因为所有记录都已获取。
我在这里错过了什么?
编辑:
从观察来看,ResultSet 将尊重语句中传递的 fetchSize,但是当我们使用all() 方法将其映射到List<MyObject> 时,它会获取数据库中的所有结果(大小 = 集群范围的 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;
}
这对性能有什么影响?
【问题讨论】:
标签: java android cassandra datastax-java-driver