Solución:
El soporte reactivo en Spring Data no proporciona medios de un Page
tipo de retorno. Aún así, el Pageable
El parámetro es compatible con las firmas de métodos que pasan limit
y offset
a los conductores y, por tanto, a la propia tienda, devolviendo un Flux<T>
que emite el rango solicitado.
Flux<Person> findByFirstname(String firstname, Pageable pageable);
Para obtener más información, consulte la Documentación de referencia actual para 2.0.RC2 y los Ejemplos de datos de Spring.
Flujo proporciona skip
y take
métodos para obtener soporte de paginación, y también puedes usar El filtro y la clasificación a continuación no es un buen ejemplo, pero use filter
y sort
para filtrar y ordenar el resultado.skip
y Pageable
como segundo parámetro no son diferentes.
Los siguientes códigos funcionan para mí.
@GetMapping("")
public Flux<Post> all(
//@RequestParam(value = "q", required = false) String q,
@RequestParam(value = "page", defaultValue = "0") long page,
@RequestParam(value = "size", defaultValue = "10") long size) {
return this.postRepository.findAll()
//.filter(p -> Optional.ofNullable(q).map(key -> p.getTitle().contains(key) || p.getContent().contains(key)).orElse(true))//(replace this with query parameters)
.sort(comparing(Post::getCreatedDate).reversed())
.skip(page * size).take(size);
}
Actualizar: Los controladores de la capa base deben ser responsables de manejar el resultado en el corrientes reactivas camino.
Y como ve en la respuesta de Christoph, si usa un findByXXX
método, Spring Data Mongo Reactive proporciona una variante para aceptar un pageable
argumento, pero el findAll
(versión reactiva) no incluye tal variante, tu tienes que hacer skip
en las operaciones posteriores si realmente necesita el paginación característica. Al cambiar a Flux
en lugar de List, imagina los datos en Flux como agua viva en los ríos o petróleo en las tuberías, o los tweets en twitter.com.
He intentado comparar las consultas usando Pageale
y no en el siguiente caso.
this.postRepository.findByTitleContains("title")
.skip(0)
.limitRequest(10)
.sort((o1, o2) -> o1.getTitle().compareTo(o2.getTitle()))
this.postRepository.findByTitleContains("title", PageRequest.of(0, 10, Sort.by(Sort.Direction.ASC, "title")))
Al habilitar el registro para logging.level.org.springframework.data.mongodb.core.ReactiveMongoTemplate=DEBUG
y descubrió que imprimen el mismo registro para las consultas.
find using query: { "title" : { "$regularExpression" : { "pattern" : ".*title.*", "options" : ""}}} fields: Document{{title=1}} for class: class com.example.demo.Post in collection: post
//other logging...
find using query: { "title" : { "$regularExpression" : { "pattern" : ".*title.*", "options" : ""}}} fields: Document{{title=1}} for class: class com.example.demo.Post in collection: post
Tenga en cuenta que todas estas operaciones deben delegado a los controladores subyacentes (si ha implementado la especificación de flujos reactivos) y se realizó en el lado de la base de datos, NO en la memoria de su aplicación.
Verifique los códigos de ejemplo.
El código de muestra anterior que proporcioné anteriormente tal vez no sea una buena muestra de filter
y sort
operaciones (MongoDB en sí proporciona una gran regularexpression
operaciones para ello). Pero la paginación en la variante reactiva no coincide con el concepto de la especificación de flujo reactivo. Al adoptar la pila reactiva de Spring, la mayoría de las veces, simplemente trasladamos nuestro trabajo a una nueva colección de API. En mi opinión, la actualización en tiempo real y la escena de respuesta elástica podrían coincidir mejor Reactivo, p.ej. usándolo con SSE, Websocket, RSocket, application/stream+json
(falta en los nuevos documentos de Spring) protocolos, etc.