Cassandra(CQL)中的结果分页

kaz*_*azy 32 cql cassandra datastax-enterprise cql3

我想知道如何使用Cassandra实现分页.

我们说我有一个博客.该博客每页最多列出10个帖子.要访问下一篇文章,用户必须单击分页菜单才能访问第2页(帖子11-20),第3页(帖子21-30)等.

在MySQL下使用SQL,我可以执行以下操作:

SELECT * FROM posts LIMIT 20,10;
Run Code Online (Sandbox Code Playgroud)

LIMIT的第一个参数从结果集的开头偏移,第二个参数是要获取的行数.上面的示例从第20行开始返回10行.

如何在CQL中实现相同的效果?

我在Google上找到了一些解决方案,但所有这些解决方案都需要"以前查询的最后结果".它适用于将"下一个"按钮分页到另一个10结果集,但如果我想从第1页跳到第5页怎么办?

Pri*_*sai 59

如果您使用的是Cassandra 2.0+,则无需使用令牌.

Cassandra 2.0具有自动分页功能.它不是使用令牌功能来创建分页,而是现在的内置功能.

现在,开发人员可以迭代整个结果集,而不必关心它的大小比内存大.当客户端代码迭代结果时,可以获取一些额外的行,而丢弃旧的行.

在Java中查看此内容,请注意SELECT语句返回所有行,并且检索的行数设置为100.

我在这里展示了一个简单的声明,但是相同的代码可以使用预准备语句编写,并与绑定语句结合使用.如果不需要,可以禁用自动分页.测试各种提取大小设置也很重要,因为你需要保持足够小的记忆,但不要太小,以至于太多的往返数据库.查看博客文章,了解分页如何在服务器端工作.

Statement stmt = new SimpleStatement(
                  "SELECT * FROM raw_weather_data"
                  + " WHERE wsid= '725474:99999'"
                    + " AND year = 2005 AND month = 6");
stmt.setFetchSize(24);
ResultSet rs = session.execute(stmt);
Iterator<Row> iter = rs.iterator();
while (!rs.isFullyFetched()) {
   rs.fetchMoreResults();
   Row row = iter.next();
   System.out.println(row);
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您正在为网页提供分页结果,那么此示例并没有真正帮助.用户可以为页面添加书签并稍后返回以期望在几天或几周后找到相同的结果.他们需要能够将令牌传回给结果中完全相同的位置恢复. (18认同)
  • 博客链接已损坏。 (3认同)

pha*_*act 10

尝试在CQL中使用令牌功能:https://docs.datastax.com/en/cql/3.1/cql/cql_reference/select_r.html#reference_ds_d35_v2q_xj__paging-through-unordered-results

另一个建议是,如果你使用DSE,solr支持深度分页:https: //cwiki.apache.org/confluence/display/solr/Pagination+of+Results

  • 还查看我们在github中的示例代码,这是一个很好的分页示例https://github.com/DataStaxCodeSamples/datastax-paging-demo (2认同)

Pri*_*sai 9

手动分页

驱动程序公开一个PagingState对象,该对象表示在获取最后一页时我们在结果集中的位置:

ResultSet resultSet = session.execute("your query");
// iterate the result set...
PagingState pagingState = resultSet.getExecutionInfo().getPagingState();
Run Code Online (Sandbox Code Playgroud)

该对象可以序列化为String或字节数组:

String string = pagingState.toString();
byte[] bytes = pagingState.toBytes();
Run Code Online (Sandbox Code Playgroud)

此序列化表单可以保存在某种形式的持久存储中,以便以后重用.当稍后检索该值时,我们可以反序列化它并将其重新注入语句中:

PagingState pagingState = PagingState.fromString(string);
Statement st = new SimpleStatement("your query");
st.setPagingState(pagingState);
ResultSet rs = session.execute(st);
Run Code Online (Sandbox Code Playgroud)

请注意,分页状态只能使用完全相同的语句(相同的查询字符串,相同的参数)重用.此外,它是一个不透明的值,仅用于收集,存储和重复使用.如果您尝试修改其内容或使用不同的语句重复使用它,驱动程序将引发错误.

Src:http://datastax.github.io/java-driver/manual/paging/

  • 如果数据库在具有"PagingState"的调用之间发生变化怎么办?它还能用吗?我知道它可能会错过这里或那里的页面,这样会很好,但它仍会找到它的方式吗?如果索引所在的页面被删除怎么办? (3认同)