【问题标题】:Spring Data reactive repositories page count and total countSpring Data 反应式存储库页面计数和总计数
【发布时间】:2021-09-10 22:33:31
【问题描述】:

在 spring Data 中,我可以轻松地执行如下查询:

Page<MyClass> findByX(String x, Pageable pageable);

reactive Spring data (MongoDB) 中,我找不到对结果进行分页的有效方法。

Mono<Page<MyClass>> findByX(String x, Pageable pageable);

似乎是一个不错的候选者,但由于需要使用 Flux.buffer(size, skip) 的错误而失败

如果没有有效的方法可以做到这一点,有没有办法在没有 Page 的情况下不实际执行一次查询来获取查询总数?

【问题讨论】:

  • 您必须将 Mono&lt;Page&lt;MyClass&gt;&gt; 更改为 Flux&lt;MyClass&gt; 然后在您的存储库中,您将能够将结果添加到内容分页并获取数据库中的总项目。
  • 这不是问题所在。当然,我可以使用 Flux(这就是使用的原因,因为找不到获取页面数据的方法)。问题是如何获取页面数据作为响应的一部分。

标签: spring spring-boot spring-data spring-webflux spring-data-mongodb


【解决方案1】:

响应式 Spring Data MongoDB 存储库不提供分页,因为它是为命令式存储库设计的。命令式分页在获取页面时需要额外的详细信息。特别是:

  • 分页查询返回的记录数
  • (可选)查询产生的记录总数,如果 返回的记录为零或与页面大小匹配以计算 总页数

这两个方面都不符合高效、非阻塞资源使用的概念。等到收到所有记录(以确定第一块分页详细信息)将消除您通过响应式数据访问获得的大部分好处。此外,执行计数查询相当昂贵,并且会增加延迟,直到您能够处理数据。

您仍然可以通过将 Pageable (PageRequest) 传递给存储库查询方法来自己获取数据块:

Flux<MyClass> findByX(String x, Pageable pageable);

Spring Data 将通过将 Pageable 转换为 LIMIT 和 OFFSET 来对查询应用分页。

Spring Documentation says:

你可以试试下面的代码,我相信它应该对你有用

Mono<Long> countByXxxx(String x);

【讨论】:

  • 感谢您的回答。我确实理解(并且错过了文档中的那部分)spring 不支持它,但我并不完全相信您的回答。请求支持分页的事实意味着无论如何,您等待数据(块)返回并等待(指定的页面大小)记录。计数查询的“价格”并不重要——一个简单的 zip 操作就足够了。有 1 个主要功能可以使用 MVC 而不是 webflux 来工作和实现。除了“它只是不支持”这一事实之外,不确定背后是否有充分的理由
  • 按照您的问题..“如果没有有效的方法,有没有办法在没有页面的情况下实际执行一次查询来获取查询总数”...我相信我的上面的答案足以查询。
  • 现在要指出当以响应方式使用时,MongoDb 存储库的分页是如何工作的,我们必须了解,使用 findByXXX 方法,Spring Data Mongo Reactive 提供了一个变体来接受可分页参数,但是findAll(reactive version) 不包含这样的变体,如果你真的需要分页功能,你必须在后面的操作中跳过。您可以在此link - Paging with the Bucket Pattern 中找到有关在分页期间如何使用不同模式的更多信息
猜你喜欢
  • 2013-05-18
  • 2015-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 2018-08-06
  • 2016-11-27
  • 1970-01-01
相关资源
最近更新 更多