gpt4 book ai didi

spring-boot - spring data mongodb聚合管道的分页结果

转载 作者:行者123 更新时间:2023-12-01 06:02:29 25 4
gpt4 key购买 nike

我在分页聚合管道的结果时遇到了一些麻烦。看完后In spring data mongodb how to achieve pagination for aggregation我想出了一个感觉像一个hacky的解决方案。我首先执行匹配查询,然后按我搜索的字段进行分组,并对结果进行计数,将值映射到私有(private)类:

private long getCount(String propertyName, String propertyValue) {
MatchOperation matchOperation = match(
Criteria.where(propertyName).is(propertyValue)
);
GroupOperation groupOperation = group(propertyName).count().as("count");
Aggregation aggregation = newAggregation(matchOperation, groupOperation);
return mongoTemplate.aggregate(aggregation, Athlete.class, NumberOfResults.class)
.getMappedResults().get(0).getCount();
}

private class NumberOfResults {
private int count;

public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}
}

这样,我就能够为返回的页面对象提供“总”值:
public Page<Athlete> findAllByName(String name, Pageable pageable) {
long total = getCount("team.name", name);
Aggregation aggregation = getAggregation("team.name", name, pageable);
List<Athlete> aggregationResults = mongoTemplate.aggregate(
aggregation, Athlete.class, Athlete.class
).getMappedResults();
return new PageImpl<>(aggregationResults, pageable, total);
}

可以看到,得到结果总数的聚合与 并没有太大区别。实际聚合 我想执行:
MatchOperation matchOperation = match(Criteria.where(propertyName).is(propertyValue));
SkipOperation skipOperation = skip((long) (pageable.getPageNumber() * pageable.getPageSize()));
LimitOperation limitOperation = limit(pageable.getPageSize());
SortOperation sortOperation = sort(pageable.getSort());
return newAggregation(matchOperation, skipOperation, limitOperation, sortOperation);

这绝对有效,但是,正如我所说,它感觉很hacky。有没有一种方法可以获取 PageImpl 实例的计数,而无需运行两次查询?

最佳答案

您的问题帮助我解决了使用聚合进行分页的相同问题,因此我进行了一些挖掘并想出了解决您问题的方法。我知道这有点晚了,但有人可能会从这个答案中受益。我绝不是 Mongo 专家,所以如果我的做法不好或表现不佳,请不要犹豫,让我知道。

使用组,我们可以将根文档添加到集合中并进行计数。

group().addToSet(Aggregation.ROOT).as("documents")
.count().as("count"))

这是我针对您面临的几乎完全相同的问题的解决方案。

private Page<Customer> searchWithFilter(final String filterString, final Pageable pageable, final Sort sort) {
final CustomerAggregationResult aggregationResult = new CustomerAggregationExecutor()
.withAggregations(match(new Criteria()
.orOperator(
where("firstName").regex(filterString),
where("lastName").regex(filterString))),
skip((long) (pageable.getPageNumber() * pageable.getPageSize())),
limit(pageable.getPageSize()),
sort(sort),
group()
.addToSet(Aggregation.ROOT).as("documents")
.count().as("count"))
.executeAndGetResult(operations);
return new PageImpl<>(aggregationResult.getDocuments(), pageable, aggregationResult.getCount());
}

CustomerAggregationResult.java

@Data
public class CustomerAggregationResult {

private int count;
private List<Customer> documents;

public static class PageableAggregationExecutor {

private Aggregation aggregation;

public CustomerAggregationExecutor withAggregations(final AggregationOperation... operations) {
this.aggregation = newAggregation(operations);
return this;
}

@SuppressWarnings("unchecked")
public CustomerAggregationResult executeAndGetResult(final MongoOperations operations) {
return operations.aggregate(aggregation, Customer.class, CustomerAggregationResult.class)
.getUniqueMappedResult();
}

}
}

真的希望这会有所帮助。

编辑:我最初使用 List 创建了一个通用的 PageableAggregationResult ,但是当我传递没有 T 类型的 PageableAggregationResult.class 时,这会返回一个 IllegalArgumentException。如果我找到解决方案,我将编辑这个答案,因为我希望能够聚合多个集合最终。

关于spring-boot - spring data mongodb聚合管道的分页结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44067505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com