在 MongoRepository<Customer,String> 中使用限制和跳过

Pra*_*ddy 4 mongodb mongodb-query spring-data-mongodb mongorepository

我们正在开发一个从 mongoDB 获取数据的项目。我们创建了存储库类,如下所示

@Repository
public interface CustomerRepository extends MongoRepository<Customer,String>{
     List<Customer> customers = findByCustomerId(final String customerId);
}
Run Code Online (Sandbox Code Playgroud)

我们希望添加跳过/偏移和限制参数作为 findByCustomerId 方法的一部分。其中 limit 用于定义返回的记录数,skip/offset 定义我们需要获取记录后的记录数。

请帮助我们如何使用 MongoRepository 以最佳方式实现这一点。

Zor*_*war 11

有两种方法可以做到这一点。

  1. 使用@Aggregation此答案中提到的注释。 /sf/answers/4990481891/

例如:

@Repository
public interface CustomerRepository extends MongoRepository<Customer,String>{

  @Aggregation(pipeline = {
    "{ '$match': { 'customerId' : ?0 } }", 
    "{ '$sort' : { 'customerId' : 1 } }", 
    "{ '$skip' : ?1 }", 
    "{ '$limit' : ?2 }"
  })
  List<Customer> findByCustomerId(final String customerId, int skip, int limit);

  @Aggregation(pipeline = {
    "{ '$match': { 'customerId' : ?0 } }", 
    "{ '$sort' : { 'customerId' : 1 } }", 
    "{ '$skip' : ?1 }"
  })
  Page<Customer> findCustomers(final String customerId, int skip, Pageable pageable);

}
Run Code Online (Sandbox Code Playgroud)

操作$match员的查询可能需要修改,以便更好地反映匹配文档需要满足的条件。

  1. Pageable在查询方法中使用参数并PageRequest从调用存储库方法的层提供参数,如本答案所示。 /sf/answers/705427411/

对于问题中的代码片段,这就变成了。

@Repository
public interface CustomerRepository extends MongoRepository<Customer,String> {

  Page<Customer> findByCustomerId(final String customerId, Pageable pageable);

}

// -------------------------------------------------------
// Call the repository method from a service
@Service
public class CustomerService {

  private final CustomerRepository customerRepository;

  public CustomerService(CustomerRepository customerRepository) {
    this.customerRepository = customerRepository;
  }

  public List<Customer> getCustomers(String customerId, int skip, int limit) {
    // application-specific handling of skip and limit arguments
    int page = 1; // calculated based on skip and limit values
    int size = 5; // calculated based on skip and limit values
    Page<Customer> page = customerRepository.findByCustomerId(customerId, 
                 PageRequest.of(page, size, Sort.Direction.ASC, "customerId"));
    List<Customer> customers = page.getContent();

    /*
    Here, the query method will retrieve 5 documents from the second 
    page.
    It skips the first 5 documents in the first page with page index 0. 
    This approach requires calculating the page to retrieve based on 
    the application's definition of limit/skip.
    */
    return Collections.unmodifiableList(customers);
  }
}
Run Code Online (Sandbox Code Playgroud)

聚合方法更有用。如果结果仅限于几个文档,则查询方法可以返回 List<Customer>. 如果有很多文档,则可以修改查询方法以使用返回文档页面的Pageable参数。Page<Customer>

请参阅 Spring Data 和 MongoDB 文档。

https://docs.spring.io/spring-data/mongodb/docs/3.2.10/reference/html/#mongo.repositories

https://docs.spring.io/spring-data/mongodb/docs/3.2.10/reference/html/#mongodb.repositories.queries.aggregation

https://docs.spring.io/spring-data/mongodb/docs/3.2.10/api/org/springframework/data/mongodb/repository/Aggregation.html

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Pageable.html

https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/PageRequest.html

MongoDB 聚合 - https://www.mongodb.com/docs/manual/meta/aggregation-quick-reference/

动态查询

自定义 Spring 数据存储库实现以及使用MongoTemplate应该有助于实现动态查询。

自定义存储库 - https://docs.spring.io/spring-data/mongodb/docs/3.2.10/reference/html/#repositories.custom-implementations

MongoTemplate- https://docs.spring.io/spring-data/mongodb/docs/3.2.10/api/org/springframework/data/mongodb/core/MongoTemplate.html