使用 spring-data-cassandra 在 cassandra 中进行分页和排序
Pagination and Sorting in cassandra using spring-data-cassandra
首先,如果 lib spring-data-cassandra 的任何开发者读我的话:谢谢你 的工作,lib 工作得很好并且很好地集成到 spring 项目中。
这里是,几天前我在尝试在 cassandra 中使用分页时遇到了一个问题。我找到了解决我的问题的方法,并将解释我是如何做到的。
我的问题如下,我一直在为 cassandra 使用分页,我不得不迭代结果切片,直到我决定在分页中使用 Sort。
为了实现这一点,我使用了:
- 使用存储库扩展 CassandraRepository
的服务
这是代码(包装存储库的服务)
public Slice<Pony> getAllByTypePage(Pageable p, EnumType type) {
Slice<Pony> slice = ponyRepository.findAllByType(p.first(), type);
//Iterate over slices
while(slice.hasNext()&&slice.getPageable().getPageNumber()<p.getPageNumber())
{
slice = ponyRepository.findAllByType(slice.nextPageable(), type);
}
return slice;
}
Pony 是我的模型 en ponyRepository 是我的 CassandraReposity
@Repository
public interface PonyRepository extends CassandraRepository<Pony,UUID> {
@Async
CompletableFuture<Long> countByType(EnumType type);
Slice<Pony> findAllByType(Pageable p,EnumType type);
}
当我尝试获取页面(第一个页面除外)时出现此异常
com.datastax.driver.core.exceptions.PagingStateException: 分页状态不匹配,这意味着分页状态内容已更改,或者您正在尝试将其应用于不同的语句
经过一些调试后,我发现我在 slice.nextPageable() 中获得的可分页对象处于 Sort.UNSORTED 模式,而不是让我的输入可分页。
然后,知道我做了这个解决方法:
public Slice<Pony> getAllByTypePage(Pageable p, EnumType type) {
Slice<Pony> slice = ponyRepository.findAllByType(p.first(), type);
//using a sidePageable and incrementing it in parallel
Pageable sidePageable = p.first();
//Iterate over slices
while(slice.hasNext()&&sidePageable.getPageNumber()<p.getPageNumber())
{
CassandraPageRequest cpr = CassandraPageRequest.of(sidePageable.next(), ((CassandraPageRequest)slice.getPageable()).getPagingState());
slice = ponyRepository.findAllByType(cpr, type);
sidePageable=sidePageable.next();
}
return slice;
}
解决方法似乎有效。
这种行为是正常现象还是错误?
我在jira中没有看到任何关于这个的问题(可能我没有看好地方)。
这是我使用的相关库 (spring boot 2.2.1/spring code 5.2.1):
spring-数据卡桑德拉:2.2.1.RELEASE
卡桑德拉驱动核心:3.7.2
我在 spring 核心 5.1.5
上看到了相同的行为
此致
正如之前的评论所说,这是一个错误。
这已经修复(请参阅之前链接的问题)。
我刚刚尝试使用快照 2.2。2.BUILD-20191113.121102-4 似乎有效。
现在我将使用我的解决方法。当库发布时我会升级。
感谢 @mp911de 的帮助
首先,如果 lib spring-data-cassandra 的任何开发者读我的话:谢谢你 的工作,lib 工作得很好并且很好地集成到 spring 项目中。
这里是,几天前我在尝试在 cassandra 中使用分页时遇到了一个问题。我找到了解决我的问题的方法,并将解释我是如何做到的。
我的问题如下,我一直在为 cassandra 使用分页,我不得不迭代结果切片,直到我决定在分页中使用 Sort。
为了实现这一点,我使用了: - 使用存储库扩展 CassandraRepository
的服务这是代码(包装存储库的服务)
public Slice<Pony> getAllByTypePage(Pageable p, EnumType type) {
Slice<Pony> slice = ponyRepository.findAllByType(p.first(), type);
//Iterate over slices
while(slice.hasNext()&&slice.getPageable().getPageNumber()<p.getPageNumber())
{
slice = ponyRepository.findAllByType(slice.nextPageable(), type);
}
return slice;
}
Pony 是我的模型 en ponyRepository 是我的 CassandraReposity
@Repository
public interface PonyRepository extends CassandraRepository<Pony,UUID> {
@Async
CompletableFuture<Long> countByType(EnumType type);
Slice<Pony> findAllByType(Pageable p,EnumType type);
}
当我尝试获取页面(第一个页面除外)时出现此异常
com.datastax.driver.core.exceptions.PagingStateException: 分页状态不匹配,这意味着分页状态内容已更改,或者您正在尝试将其应用于不同的语句
经过一些调试后,我发现我在 slice.nextPageable() 中获得的可分页对象处于 Sort.UNSORTED 模式,而不是让我的输入可分页。
然后,知道我做了这个解决方法:
public Slice<Pony> getAllByTypePage(Pageable p, EnumType type) {
Slice<Pony> slice = ponyRepository.findAllByType(p.first(), type);
//using a sidePageable and incrementing it in parallel
Pageable sidePageable = p.first();
//Iterate over slices
while(slice.hasNext()&&sidePageable.getPageNumber()<p.getPageNumber())
{
CassandraPageRequest cpr = CassandraPageRequest.of(sidePageable.next(), ((CassandraPageRequest)slice.getPageable()).getPagingState());
slice = ponyRepository.findAllByType(cpr, type);
sidePageable=sidePageable.next();
}
return slice;
}
解决方法似乎有效。
这种行为是正常现象还是错误?
我在jira中没有看到任何关于这个的问题(可能我没有看好地方)。
这是我使用的相关库 (spring boot 2.2.1/spring code 5.2.1):
spring-数据卡桑德拉:2.2.1.RELEASE 卡桑德拉驱动核心:3.7.2
我在 spring 核心 5.1.5
上看到了相同的行为此致
正如之前的评论所说,这是一个错误。 这已经修复(请参阅之前链接的问题)。
我刚刚尝试使用快照 2.2。2.BUILD-20191113.121102-4 似乎有效。
现在我将使用我的解决方法。当库发布时我会升级。
感谢 @mp911de 的帮助