Consulta SQL++ / N1QL

Consultas de datos por paginación con N1QL

M. David Allen es un ingeniero de software y emprendedor que lleva más de una década trabajando con casi todos los lenguajes de programación y tipos de sistemas de bases de datos a su alcance. David ha trabajado anteriormente en muchos sectores, como las finanzas, la sanidad y la administración pública, centrándose normalmente en retos de integración de datos a gran escala, la transición de la investigación aplicada y la innovación de nuevas tecnologías. Tiene un máster por la Virginia Commonwealth University, pero desde que abandonó la educación formal sigue siendo un estudiante permanente de tecnología.

Configurar

En este tutorial, utilizaremos la función conjunto de datos de la muestra de cerveza que viene con Couchbase para que sea fácil seguirlo. Si todavía no tienes Couchbase instalado, puedes ponerte en marcha muy rápidamente teniendo docker y siguiendo las sencillas instrucciones de la página de imágenes docker de couchbase para configurar una instancia rápida de Couchbase para pruebas. Simplemente ejecutando el comando docker run -d -name db -p 8091-8094:8091-8094 -p 11210:11210 Couchbase con Couchbase instalado podemos empezar. Después de seguir algunas instrucciones de configuración descritas en esa página, estamos listos para rodar con algunos datos.

Casos prácticos - ¿Qué es el paginado y por qué hacerlo?

Consideremos una necesidad muy común; en nuestra hipotética aplicación front-end de cerveza, queremos mostrar a nuestros usuarios una tabla de cervezas y dejar que valoren cada una de ellas. El problema es que la base de datos contiene más de 5.000 cervezas. Sería un desperdicio enviar todo el conjunto de datos al navegador cada vez, y ralentizaría mucho la carga de la página de tu aplicación web.

Mucho mejor sería mostrar al usuario sólo las 10 primeras cervezas. Entonces, haciendo clic en un botón "Siguiente" para ir a la página siguiente, o incluso mejor utilizando un plugin de desplazamiento infinito (como ngInfiniteScroll para ángulos o react-infinite para reaccionar) se pueden mostrar al usuario progresivamente más registros de la base de datos.

¡Enséñame el Código!

Esto devuelve los datos que cabría esperar:

Para obtener la segunda página de resultados, sólo tiene que añadir el LÍMITE al OFFSET. Por ejemplo, OFFSET 10 LIMIT 10 sería la segunda página. Para generalizar, ¿cuántos registros debe omitir con OFFSET para llegar a la enésima página? Siempre será n * tamaño de página.

Utilizando esta sencilla matemática, podemos generalizarlo a cualquier escenario. ¿Qué pasaría si quisiéramos mostrar 20 resultados a la vez, y el usuario quisiera saltar directamente a la página 11? No hay problema, basta con LIMIT 20 OFFSET 20 * 11. Así, los extremos de la aplicación, ya estén buscando en la base de datos o simplemente listando cervezas por nombre, pueden utilizar exactamente la misma lógica de consulta cada vez. No importa lo compleja que sea la consulta, basta con ajustar LIMIT y OFFSET y todos estaremos en la misma página.

¿Cómo funciona?

La magia aquí es la combinación de tres cláusulas N1QL:  LÍMITE, OFFSETy ORDENAR POR. Echemos un vistazo rápido a cada uno de ellos, porque todos son necesarios para hacer el trabajo.

  • LÍMITE hace exactamente lo que dice. Limita el número de registros que Couchbase devolverá, y refuerza de forma efectiva el tamaño de nuestra página (sólo queremos 10 cervezas a la vez, nunca 5.000).
  • OFFSET le dice a Couchbase cuántos registros saltar antes de empezar a devolver documentos. Si estás familiarizado con SQL, se comporta igual que SKIP en SQL. La cláusula OFFSET es la forma en que nos movemos hacia adelante a través de todo el conjunto de datos un trozo a la vez.
  • ORDENAR POR garantiza un cierto orden devuelto por la base de datos. Esto es importante porque Couchbase no garantiza ningún orden particular de los resultados a menos que lo pidas. En nuestra consulta anterior, la #17 Cream Ale apareció como primer resultado al ordenar por nombre. Si no usáramos ORDER BY, no podríamos predecir en qué parte del conjunto aparecería la #17 Cream Ale, ¡y podría ser posible que apareciera en más de una página dependiendo de cómo Couchbase ejecutara la consulta!

En pocas palabras, imagina que Couchbase construye una lista de todas las cervezas ordenadas por nombre (ORDER BY). La paginación es simplemente tomar lotes de 10 de ellas (LIMIT 10). Cada página comienza saltando a través de toda la lista ordenada hasta el punto de inicio de la página siguiente (OFFSET).

Explícate, Couchbase.

Un último ejemplo; como con cualquier consulta N1QL, puedes obtener mucha información sobre cómo funciona simplemente poniendo "EXPLAIN" delante de ella. Esto le dice a Couchbase que te diga lo que está planeando hacer.

(La salida es bastante larga, así que no la pegaremos aquí, pero vamos a resumir lo que Couchbase está haciendo con esta consulta.

  1. Primero realiza un escaneo primario del cubo de muestras de cerveza y obtiene los documentos.
  2. Paralelamente, filtra por:
    1. Registros que tienen un brewery_id (esto nos dice que el registro es una cerveza, no un documento de cervecería)
    2. Proyecta el nombre, la categoría y las propiedades del abv (lo que pedimos).
  3. A continuación, ordena los resultados por nombre
  4. El desplazamiento se aplica a continuación, saltándose los primeros X registros y no devolviéndolos en absoluto.
  5. Por último, aplica el LÍMITE leyendo los n registros siguientes, e ignorando todos los que le siguen.

¿Cuándo terminamos?

Si avanzamos por los datos página a página, también tenemos que saber cuándo detenernos. Hay dos maneras de enfocar esto; por un lado, si seguimos avanzando a través de las páginas indefinidamente, eventualmente nos quedaremos sin datos. Por otro lado, podemos calcular cuántas páginas hay e iterar hasta llegar a ese número.

¿Qué ocurre si pedimos la 7ª página de 1.000 resultados, sabiendo perfectamente que no existe tal conjunto de documentos?

Bueno, no temas: si pasas del final, sólo obtendrás una matriz vacía.

Para que conste, la matriz vacía es también lo que obtendrás si pides tonterías, como:

Espere.... ¡¿Qué?! Esta consulta pide que se inicie 5 registros antes del principio del conjunto de salida y que no devuelva más de -10 registros. 5 registros antes del comienzo no es nada. Y no más de -10 registros no es nada. ¡Así que se obtiene....nada!

Este comportamiento es muy conveniente; es claro cuando te quedas sin registros, y también juega muy bien con un montón de otras suposiciones en diferentes capas de software. Si alguna vez has utilizado API REST que admiten paginación, así es como suelen funcionar. Por ejemplo, puede imaginar fácilmente un punto final de la API REST con el siguiente aspecto: http://cool-app.com/beers?limit=10&page=6000. Si escribes un endpoint así en tu back-end, puedes ver fácilmente cómo generaría una consulta N1QL correspondiente, e incluso si el usuario te diera un número de página raro, tu endpoint haría lo correcto.

Pero, ¿y si quiero saber de antemano cuántas páginas habrá?

Esto también es sencillo. Si sabemos que cada página tiene n registros, y conocemos el número total de registros, entonces podemos dividir el total por n, tomar el techo de ese número, y eso nos dirá cuántas páginas potenciales hay en Couchbase.

Esto produce en mi base de datos local 590. Como hay exactamente 5.891 documentos de cerveza, eso significa que habrá 589 conjuntos de 10, y que la página final sólo tendrá 1 documento. Como 5.891 / 10 = 589,1, usamos el N1QL Función CEIL para obtener un número entero de páginas, ya que cualquier aplicación front-end no va a mostrar 0,1 de una página.

Tenga en cuenta que aún necesitamos la cláusula WHERE aquí, para reducir los documentos a sólo los de cerveza, excluyendo los de cervecería y otros. Si faltara la cláusula WHERE, seguro que obtendría un número incorrecto.

 

Este post forma parte del Programa de Escritura de la Comunidad Couchbase

Comparte este artículo
Recibe actualizaciones del blog de Couchbase en tu bandeja de entrada
Este campo es obligatorio.

Autor

Publicado por Laura Czajkowski, Directora de la Comunidad de Desarrolladores, Couchbase

Laura Czajkowski es la Snr. Developer Community Manager en Couchbase supervisando la comunidad. Es responsable de nuestro boletín mensual para desarrolladores.

Deja un comentario

¿Listo para empezar con Couchbase Capella?

Empezar a construir

Consulte nuestro portal para desarrolladores para explorar NoSQL, buscar recursos y empezar con tutoriales.

Utilizar Capella gratis

Ponte manos a la obra con Couchbase en unos pocos clics. Capella DBaaS es la forma más fácil y rápida de empezar.

Póngase en contacto

¿Quieres saber más sobre las ofertas de Couchbase? Permítanos ayudarle.