Flux提供skip和take方法来获得分页支持,你也可以使用filter和sort对结果进行过滤和排序。 下面的过滤和排序不是一个很好的例子,但是使用skip和Pageable作为第二个参数没有什么不同。
以下代码对我有用。
@GetMapping("")
public Flux<Post> all(
//@RequestParam(value = "q", required = false) String q,
@RequestParam(value = "page", defaultValue = "0") long page,
@RequestParam(value = "size", defaultValue = "10") long size) {
return this.postRepository.findAll()
//.filter(p -> Optional.ofNullable(q).map(key -> p.getTitle().contains(key) || p.getContent().contains(key)).orElse(true))//(replace this with query parameters)
.sort(comparing(Post::getCreatedDate).reversed())
.skip(page * size).take(size);
}
更新:底层驱动程序应负责以 reactivestreams 方式处理结果。
正如您在 Christoph 的回答中看到的那样,如果使用 findByXXX 方法,Spring Data Mongo Reactive 提供了一个接受 pageable 参数的变体,但 findAll(reactive version) 没有包含这样一个变体,如果你真的需要分页功能,你必须在后面的操作中做skip。当切换到 Flux 而不是 List 时,将 Flux 中的数据想象成河流中的活水或管道中的石油,或者 twitter.com 中的推文。
我尝试比较使用Pageale 的查询,而不是在以下情况下。
this.postRepository.findByTitleContains("title")
.skip(0)
.limitRequest(10)
.sort((o1, o2) -> o1.getTitle().compareTo(o2.getTitle()))
this.postRepository.findByTitleContains("title", PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "title")))
当为logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG 启用日志记录时,发现它们为查询打印相同的日志。
find using query: { "title" : { "$regularExpression" : { "pattern" : ".*title.*", "options" : ""}}} fields: Document{{title=1}} for class: class com.example.demo.Post in collection: post
//other logging...
find using query: { "title" : { "$regularExpression" : { "pattern" : ".*title.*", "options" : ""}}} fields: Document{{title=1}} for class: class com.example.demo.Post in collection: post
请记住,所有这些操作都应该委派给底层驱动程序(如果它已实现反应流规范)并在数据库端执行,不您的应用程序端的内存。
检查example codes。
我上面提供的早期示例代码可能不是filter 和sort 操作的好示例(MongoDB 本身为它提供了很好的regularexpression 操作)。但是反应变体中的分页与反应流规范中的概念并不匹配。在采用 Spring 反应式堆栈时,大多数时候,我们只是将工作转移到新的 API 集合中。在我看来,实时更新和弹性响应场景可以更好地匹配Reactive,例如。将它与 SSE、Websocket、RSocket、application/stream+json(在新的 Spring 文档中缺失)协议等一起使用