使用 mongoTemplate 进行分页

Pagination with mongoTemplate

我有一个可分页的查询:

Query query = new Query().with(new PageRequests(page, size))

如何使用 MongoTemplate 执行它?我没有看到返回 Page<T>.

的单一方法

MongoTemplate 没有 return Page 的方法。 find() 方法 return 一个普通的 List.

with(new PageRequests(page, size) 在内部用于通过 MongoDB 查询调整 skiplimit(我认为是计数查询)

Page 可以与 MongoDB repositories 结合使用,后者是 Spring 数据存储库的特例。

因此,您必须使用 MongoRepositoryPage findAll(Pageable pageable) 来获得分页结果(实际上继承自 PagingAndSortingRepository)。

的确 MongoTemplate 没有 findXXX 和 Pageables。

但是您可以为此使用 Spring 存储库 PageableExecutionUtils

在您的示例中,它看起来像这样:

Pageable pageable = new PageRequests(page, size);
Query query = new Query().with(pageable);
List<XXX> list = mongoTemplate.find(query, XXX.class);
return PageableExecutionUtils.getPage(
                       list, 
                       pageable, 
                       () -> mongoTemplate.count(Query.of(query).limit(-1).skip(-1), XXX.class));

与原始的 Spring 数据存储库一样,PageableExecutionUtils 将执行计数请求并将其包装成一个漂亮的 Page 为您服务。

Here 你可以看到 spring 也在做同样的事情。

基于 d0x 的回答并查看 spring code。我正在使用这种变体,它可以解决 spring-boot-starter-data-mongodb 依赖关系,而无需添加 spring 数据共享。

@Autowired
private MongoOperations mongoOperations;

@Override
public Page<YourObjectType> searchCustom(Pageable pageable) {
    Query query = new Query().with(pageable);
    // Build your query here

    List<YourObjectType> list = mongoOperations.find(query, YourObjectType.class);
    long count = mongoOperations.count(query, YourObjectType.class);
    Page<YourObjectType> resultPage = new PageImpl<YourObjectType>(list , pageable, count);
    return resultPage;
}
return type Mono<Page<Myobject>>...

return this.myobjectRepository.count()
        .flatMap(ptiCount -> {
          return this.myobjectRepository.findAll(pageable.getSort())
            .buffer(pageable.getPageSize(),(pageable.getPageNumber() + 1))
            .elementAt(pageable.getPageNumber(), new ArrayList<>())
            .map(ptis -> new PageImpl<Myobject>(ptis, pageable, ptiCount));
        });

默认情况下,spring mongo 模板没有按页查找的方法。它搜索 returns 整个记录列表。我试过了,它起作用了:

Pageable pageable = new PageRequests(0, 10);                              
Query query = new Query(criteria); 
query.with(pageable);   
List<User> lusers = mt.find(query, User.class);   
Page<User> pu = new PageImpl<>(lusers, pageable, mongoTemplate.count(newQuery(criteria), User.class));

None 此处提供的解决方案适用于我自己的情况。 我尝试从媒体 post 使用下面的这个解决方案,它从未返回分页结果,但 returns 所有结果都不是我期望的

return PageableExecutionUtils.getPage(
        mongoTemplate.find(query, ClassName.class),
        pageable,
        () -> mongoTemplate.count(query.skip(0).limit(0), ClassName.class)
);

所以我找到了一个更好的方法来解决这个问题并且它在我的案例中有效:

return PageableExecutionUtils.getPage(
            mongoTemplate.find(query.with(pageable), ClassName.class),
            pageable,
            () -> mongoTemplate.count(query, ClassName.class));