public class Result<T> {
int totalCount;
List<T> objects;
}
public <T, R extends Result<T>> R executePaged(Class<T> inputType,
Criteria criteria,
Pageable pageable,
Class<R> resultType) {
var match = Aggregation.match(criteria);
var facets = Aggregation
.facet(
Aggregation.sort(pageable.getSort()),
Aggregation.skip(pageable.getOffset()),
Aggregation.limit(pageable.getPageSize())
).as("objects")
.and(
Aggregation.count().as("count")
).as("countFacet");
var project = Aggregation
.project("objects")
.and("$countFacet.count").arrayElementAt(0).as("totalCount");
var aggregation = Aggregation.newAggregation(match, facets, project);
return mongoTemplate.aggregate(aggregation, inputType, resultType)
.getUniqueMappedResult();
}
注:
扩展并参数化Result<T>以作为resultType传递,否则反序列化器不知道使用哪个类
必须使用Sort创建pageable
如果需要,您仍然可以在以后创建PageImpl
示例:
class Person {
String name;
Date birthdate;
}
class PersonResult extends Result<Person>{}
PersonResult result = executePaged(Person.class,
Criteria.where("name").is("John"),
PageRequest.of(3, 50).withSort(Sort.by("birthdate")),
PersonResult.class);
System.out.println("Total #Johns: " + result.totalCount);
System.out.println("Johns on this page: " + result.objects);
7条答案
按热度按时间iyr7buue1#
的确,
MongoTemplate
没有带可分页功能的findXXX
。但是您可以使用Spring存储库
PageableExecutionUtils
来实现这一点。在您的示例中,它将如下所示:
与最初的Spring Data Repository一样,
PageableExecutionUtils
将执行一个计数请求,并将其 Package 成一个漂亮的Page
。在这里你可以看到Spring也在做同样的事情。
ttisahbt2#
基于d 0x的回答,并查看spring代码,我使用了这个变体,它消除了spring-boot-starter-data-mongodb依赖,而不需要添加spring数据公共项。
6rvt4ljy3#
MongoTemplate
没有返回Page
的方法。find()
方法返回普通的List
。with(new PageRequests(page, size)
在内部用于通过MongoDB查询(我认为是通过计数查询进行)调整skip
和limit
Page
可以与MongoDB存储库结合使用,MongoDB存储库是Spring Data 存储库的一种特殊情况。因此,必须使用
MongoRepository
的Page findAll(Pageable pageable)
来对结果进行分页(实际上是从PagingAndSortingRepository
继承而来的)。gwo2fgha4#
默认情况下,spring mongo模板没有按页查找的方法。它搜索并返回整个记录列表。我试过了,它工作了:
qnzebej05#
这里提供的解决方案都不适用于我自己的情况。我试着使用下面的解决方案从一个中等职位,它从来没有返回分页的结果,但返回所有的结果,这不是我所期望的
所以我找到了一个更好的方法,它在我的情况下工作:
cclgggtu6#
到目前为止,所有答案都执行查询两次。这通常不是您想要的。下面是一个使用聚合只运行一次的解决方案。
注:
Result<T>
以作为resultType
传递,否则反序列化器不知道使用哪个类Sort
创建pageable
PageImpl
示例:
kwvwclae7#