我们正在尝试制作一个从cassandra db返回UI分页结果的应用程序。
UI会将fetchSize
和pagingState
传递给我们的API,并基于此返回List<MyObject>
中的size=fetchSize
。如果传递了pagingState
,我们将从上一页继续进行查询(如cassandra docs中所述:https://docs.datastax.com/en/developer/java-driver/3.6/manual/paging/)
请注意,我正在使用3.6版的Cassandra驱动程序。
但是当我们实现它时,Cassandra总是返回数据库中的所有条目,而忽略获取大小,这反过来会导致null
的{{1}}值。我该如何解决?
我在数据库中为ResultSet.getExecutionInfo().getPagingState()
创建了16条记录,并尝试将获取大小传递为5以获取它们。所有16条记录都具有相同的分区键MyObject
。
ID-1
在上面的代码中,我希望Cassandra返回5个// 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();
对象的列表,并为我的MyObject
变量提供一个字符串值。
两者都不如预期。
列表的大小为16(基本上已获取所有记录)
由于上述原因,pageState
之所以是pageState
,因为所有记录都已被提取。
我在这里想念什么?
编辑:
根据观察,null
将遵守在语句中传递的fetchSize,但是当我们使用ResultSet
方法将其映射到List<MyObject>
时,它将获取数据库中的所有结果(大小=群集范围的fetchSize) 。
因此,当我多次调用all()
方法5(= Result#one
)次并将它们推送到List中时,我得到了分页状态以及页面大小的结果。
上面的示例Util方法
pageSize
这对性能有何影响?
答案 0 :(得分:2)
如您所见,尽管您指定了setFetchSize
,但仍获得所有结果的原因是,因为获取大小只是设置了每个请求页面的请求大小。调用all()
时,驱动程序将透明浏览所有结果。
与one()
相比,单独调用all()
不会对性能产生影响,但是我建议更改您使用该页面的逻辑,因为如果您这样做,IntStream.range(1, pageSize)
会失败已经用尽了您的结果集(即,将获取大小设置为500,但是只有495行)。相反,您可以使用IntStream.range(1, resultSet.getAvailableWithoutFetching())
。
您还可以选择遍历结果集,直到ResultSet.isExhausted()
返回true为止,以防止获取下一页。