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

如何使用MongoTemplate获取非嵌套文档分片结果及分页结果

Hey there! Let's tackle your two questions about pagination with MongoTemplate clearly and practically.

一、How to get paginated results for non-nested documents with MongoTemplate?

To implement proper pagination, you need two key pieces: the data for the current page, and the total number of matching records (to calculate total pages, next/previous page status, etc.). Here's a step-by-step breakdown with code:

  • Define pagination parameters: Use PageRequest (implements Pageable) to set the 0-indexed page number and page size.
  • Build query criteria: For non-nested documents, reference fields directly in your Criteria.
  • Fetch current page data: Use mongoTemplate.find() with your paginated Query.
  • Count total matching records: Create a copy of your query without pagination (skip/limit) to get the full count of documents that match your criteria.
  • Wrap into a Page object: Use PageImpl (Spring Data's default Page implementation) to combine the data, pagination info, and total count.

Example code:

// 1. Set up pagination
int pageNumber = 0; // First page (0-indexed)
int pageSize = 15;
Pageable pageable = PageRequest.of(pageNumber, pageSize);

// 2. Build criteria for non-nested document
Criteria criteria = Criteria.where("status").is("PAID");
Query paginatedQuery = new Query(criteria).with(pageable);

// 3. Get current page content
List<Invoice> currentPageContent = mongoTemplate.find(paginatedQuery, Invoice.class);

// 4. Get total number of matching records (remove pagination from query)
Query countQuery = new Query(criteria);
long totalRecords = mongoTemplate.count(countQuery, Invoice.class);

// 5. Create the Page object
Page<Invoice> paginatedResult = new PageImpl<>(currentPageContent, pageable, totalRecords);

This gives you a fully functional Page object with all pagination metadata (total pages, current page number, hasNext/hasPrevious, etc.).

二、Fixing your specific pagination scenario

Looking at your code, the main issue is that mongoTemplate.find() returns a List<Invoice>, not a Page<Invoice>—so your assignment will throw a compilation error. Additionally, you're not calculating the total number of matching records, which is essential for proper pagination.

Here's the corrected version of your code:

final Pageable pageableRequest = PageRequest.of(offset, limit);
// Initialize Criteria properly (avoid where("") which can cause unexpected behavior)
Criteria criteria = new Criteria();

if (null != type) {
    criteria = criteria.and("type").is(type);
}
if (null != revision) {
    criteria = criteria.and("current_revision_data.data.revision_start").is(revision);
}

// 1. Create paginated query
Query paginatedQuery = new Query(criteria).with(pageableRequest);

// 2. Fetch current page data
List<Invoice> invoiceList = mongoTemplate.find(paginatedQuery, Invoice.class);

// 3. Count total matching records (no pagination parameters)
Query countQuery = new Query(criteria);
long totalCount = mongoTemplate.count(countQuery, Invoice.class);

// 4. Wrap into a Page object
Page<Invoice> invoices = new PageImpl<>(invoiceList, pageableRequest, totalCount);

Bonus: Simplify with Spring Data MongoDB's fluent API (2.x+)

If you're using a recent version of Spring Data MongoDB, you can use the fluent query API to avoid manual count calls—it handles the total count automatically:

Page<Invoice> invoices = mongoTemplate.query(Invoice.class)
    .matching(new Query(criteria).with(pageableRequest))
    .page(pageableRequest);

This is cleaner and reduces boilerplate code.


内容的提问来源于stack exchange,提问作者Kency Kurian

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:29:09