You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取MongoDB分页总页数?附现有实现代码与数据

Fixing MongoDB Pagination Total Pages Calculation

Hey there! The issue you're facing with incorrect totalPages is because right now you're passing filter.size() (the number of elements in the current page) as the total element count to PageImpl. To get the correct total pages, you need to first calculate the total number of documents that match your query criteria, not just the ones loaded for the current page.

Let's fix this step by step:

1. Extract Shared Query Criteria

First, pull out your search criteria into a reusable variable to avoid duplicating code across count and pagination queries:

Criteria criteria = new Criteria().orOperator(
    Criteria.where("name").regex(query, "i"),
    Criteria.where("details.brand").regex(query, "i"),
    Criteria.where("details.tags.tags1").regex(query, "i"),
    Criteria.where("details.tags.tags2").regex(query, "i"),
    Criteria.where("details.tags.tags3").regex(query, "i")
);

2. Calculate Total Matching Documents

You need to get the total number of documents that fit your search terms. There are two straightforward ways to do this:

Option 1: Use mongoTemplate.count() (Simplest for Basic Counts)

This is the cleanest approach if you don't need complex aggregation logic for counting:

Long totalElements = mongoTemplate.count(Query.query(criteria), "Product");

Option 2: Use Aggregation Count (For Complex Scenarios)

If you ever need to add grouping or other logic to your count, use an aggregation pipeline:

Aggregation countAggregation = Aggregation.newAggregation(
    Aggregation.match(criteria),
    Aggregation.count().as("total")
);
Long totalElements = mongoTemplate.aggregate(countAggregation, "Product", Document.class)
    .getMappedResults()
    .stream()
    .findFirst()
    .map(doc -> doc.getLong("total"))
    .orElse(0L);

3. Update Pagination Aggregation to Use Pageable

Instead of hardcoding skip(page *4) and limit(4), leverage the pageable parameter you're already receiving. This makes your code flexible to different page sizes configured by the caller:

Aggregation paginationAggregation = Aggregation.newAggregation(
    Aggregation.match(criteria),
    Aggregation.skip(pageable.getOffset()), // Automatically computes pageNumber * pageSize
    Aggregation.limit(pageable.getPageSize())
);
List<Products> filter = mongoTemplate.aggregate(paginationAggregation, "Product", Products.class).getMappedResults();

4. Return PageImpl with Correct Total Elements

Finally, pass the real totalElements (not the current page's size) to the PageImpl constructor. This lets Spring's PageImpl calculate the correct totalPages automatically:

return new PageImpl<>(filter, pageable, totalElements);

Full Updated Method

@GetMapping("/engine/search") 
public PageImpl<Products> engineSearch(@RequestParam("p") String query, @RequestParam(value = "page", defaultValue = "0") int page, Pageable pageable) { 
    // Define shared search criteria
    Criteria criteria = new Criteria().orOperator(
        Criteria.where("name").regex(query, "i"),
        Criteria.where("details.brand").regex(query, "i"),
        Criteria.where("details.tags.tags1").regex(query, "i"),
        Criteria.where("details.tags.tags2").regex(query, "i"),
        Criteria.where("details.tags.tags3").regex(query, "i")
    );

    // Get total number of matching documents
    Long totalElements = mongoTemplate.count(Query.query(criteria), "Product");

    // Build pagination aggregation
    Aggregation paginationAggregation = Aggregation.newAggregation(
        Aggregation.match(criteria),
        Aggregation.skip(pageable.getOffset()),
        Aggregation.limit(pageable.getPageSize())
    );
    List<Products> filter = mongoTemplate.aggregate(paginationAggregation, "Product", Products.class).getMappedResults();

    // Return properly populated PageImpl
    return new PageImpl<>(filter, pageable, totalElements); 
}

Why This Fixes the Total Pages Issue

  • The totalElements variable now holds the full count of documents matching your search, not just the subset in the current page.
  • PageImpl uses this total count and the pageable's pageSize to compute totalPages using the formula: ceil(totalElements / pageSize) (exactly what you need for accurate pagination metadata).
  • Using pageable.getOffset() and pageable.getPageSize() aligns your code with Spring Data's standard pagination patterns, making it more maintainable and flexible.

内容的提问来源于stack exchange,提问作者Taylor Marshall

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 12:27:49