【问题标题】:Implementing pagination and sorting on a ReactiveMongoRepository with a dynamic query使用动态查询在 ReactiveMongoRepository 上实现分页和排序
【发布时间】:2020-07-27 23:29:08
【问题描述】:

我知道分页有点违反反应性原则,但由于要求,我必须以某种方式使其工作。我正在使用 Spring Data 2.1.6,我无法升级,所以 ReactiveQuerydslSpecification 动态查询是不可能的。我想我可以使用ReactiveMongoTemplate,所以我想出了这个:

public interface IPersonRepository extends ReactiveMongoRepository<Person, String>, IPersonFilterRepository {
    Flux<Person> findAllByCarId(String carId);
}

public interface IPersonFilterRepository {
    Flux<Person> findAllByCarIdAndCreatedDateBetween(String carId, PersonStatus status,
                                                             OffsetDateTime from, OffsetDateTime to,
                                                             Pageable pageable);
}

@Repository
public class PersonFilterRepository implements IPersonFilterRepository {

    @Autowired
    private ReactiveMongoTemplate reactiveMongoTemplate;

    @Override
    public Flux<Person> findAllByCarIdAndCreatedDateBetween(String carId, PersonStatus status,
                                                                   OffsetDateTime from, OffsetDateTime to,
                                                                   Pageable pageable) {
        Query query = new Query(Criteria.where("carId").is(carId));

        if (status != null) {
            query.addCriteria(Criteria.where("status").is(status));
        }

        OffsetDateTime maxLimit = OffsetDateTime.now(ZoneOffset.UTC).minusMonths(3).withDayOfMonth(1); // beginning of month
        if (from == null || from.isBefore(maxLimit)) {
            from = maxLimit;
        }

        query.addCriteria(Criteria.where("createdDateTime").gte(from));

        if (to == null) {
            to = OffsetDateTime.now(ZoneOffset.UTC);
        }

        query.addCriteria(Criteria.where("createdDateTime").lte(to));

        // problem is trying to come up with a decent page-ish behavior compatible with Flux
        /*return reactiveMongoTemplate.count(query, Person.class)
                .flatMap(count -> reactiveMongoTemplate.find(query, Person.class)
                        .flatMap(p -> new PageImpl<Person>(p, pageable, count))
                        .collectList()
                        .map());*/

        /* return reactiveMongoTemplate.find(query, Person.class)
                .buffer(pageable.getPageSize(), pageable.getPageNumber() + 1)
                //.elementAt(pageable.getPageNumber(), new ArrayList<>())
                .thenMany(Flux::from);*/
    }

我试图返回一个Page&lt;Person&gt;(假设一次这个单一方法可能是非反应性的,一次)并且它在运行测试时失败并出现以下错误(Spring 上下文未成功加载,原因是:@ 987654326@。我也尝试过返回Mono&lt;Page&lt;Person&gt;&gt;,然后以"Method has to use a either multi-item reactive wrapper return type or a wrapped Page/Slice type. Offending method: 'IDocumentFilterRepository.findAllByCustomerIdAndCreatedDateBetween' 失败,所以我想我唯一的选择是返回Flux,根据Example 133, snippet 3

【问题讨论】:

    标签: reactive-programming spring-data-mongodb project-reactor


    【解决方案1】:

    事实证明,您只需将以下内容添加到查询对象中:

    query.with(pageable);
    
    reactiveMongoTemplate.find(query, Person.class);
    

    返回Flux&lt;T&gt;,它会开箱即用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 2015-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-05
      相关资源
      最近更新 更多