Este blog anterior repasa los fundamentos de la ejecución de sentencias N1QL dentro de funciones JavaScript.

Ahora pasamos a...

Iteradores/Valores de procesamiento

Hasta ahora hemos evitado a propósito las declaraciones que devuelven datos, y la devolución de datos de la función.

Aquí es donde empezamos a explorar la recopilación de datos.

En N1QL() referenciada directamente o a través de la magia del transpilador, devuelve un manejador de sentencia. El manejador viene en forma de objeto JavaScript y tiene un iterador asociado, por ejemplo:

No voy a dedicar mucho tiempo a describir los iteradores, así que aquí están los conceptos básicos:

  • Puede obtener el siguiente valor de un iterador utilizando la función next() método.
  • En hecho es verdadera si no hay más documentos que obtener.
  • Aunque puede utilizar el iterador next() y hecho en un bucle while para obtener todos los documentos, una construcción más legible es el método para..de bucle sobre el propio manejador de sentencia.
  • No es necesario recuperar todos los valores: puede descartar una sentencia en cualquier momento llamando a la función de la sentencia cerrar() aunque, como veremos más adelante, no es necesario hacerlo.

Ponerlo todo junto:
Basics of iterators in N1QL/JavaScript and Couchbase
y la función correspondiente:

En este ejemplo, una matriz denominada res acumula los documentos que obtenemos de b1 a través del iterador qy, a continuación, se utiliza para devolverlos a la persona que los solicita.

Un par de notas al margen

En términos generales, probablemente sea mejor procesar los valores de la consulta a medida que se reciben en el archivo para en lugar de acumularlos en una matriz, ya que esto tiene implicaciones de uso de memoria transitoria.

A la inversa, devolver un valor de matriz desde una función permite que una sentencia seleccione de la función, por ejemplo:

Esto es muy parecido a lo que haría con las funciones de tabla o las tablas derivadas de colecciones que ha encontrado en el mundo relacional.

En el mundo N1QL se conocen como exploraciones de expresión.

Por supuesto, va por sí mismo que si todo lo que quieres que tu función haga es devolver algunos documentos de un espacio clave sin más lógica, probablemente sea mejor escribir una función en línea.

De vuelta al iterador

Una vez que haya terminado de procesar los valores, el iterador se cierra automáticamente, por lo que no tiene que hacer nada.

Si el iterador no se vacía, es una buena práctica cerrarlo, aunque no es estrictamente necesario, ya que se cerrará automáticamente cuando la función regrese, así como en otras circunstancias como veremos más adelante.

Dentro de la para ... de ... es perfectamente válido tener otras declaraciones N1QL: algunas cosas a tener en cuenta se describirán en secciones posteriores.

Valores de procesamiento

Intentemos utilizar los valores devueltos por el select, en lugar de devolverlos sin más:

Nada especialmente sofisticado, sólo extraer un campo del documento.

Ejecutando esta función se obtiene:

¿Qué ocurre? ¿Por qué no vuelve f1?

Podemos adivinar la respuesta ejecutando:

Y viendo, en la IU:

f1 es un campo de b1y no el documento seleccionado.

Cualquiera de ellos hace lo que quieres:

 

Sentencias DML

Considera la siguiente función:

Esta función crea nuevos documentos en b1 copiándolos de los documentos existentes y elimina los documentos antiguos.

El hecho de que q1 y q2 son iteradores, incluso cuando las sentencias no devuelven valores no debería sorprendernos demasiado: como veremos más adelante, las sentencias DML pueden devolver valores, y lo que es peor, el transpilador no siempre puede determinar si se están devolviendo valores o no, de ahí que la sentencia N1QL() siempre devuelve un iterador.

La implicación de esto es que una vez que el N1QL() la sentencia N1QL puede estar ejecutándose de forma asíncrona en segundo plano, dejando la función JavaScript libre para ejecutar otro código antes de obtener los datos.

En jsevaluator elimina cualquier ambigüedad de comportamiento obligando a las sentencias que no devuelven valores a ejecutarse inmediatamente y en serie, lo que significa que esperará a que se complete cada sentencia DML antes de que comience la siguiente.

No es necesaria ninguna acción sobre el iterador, ni siquiera cerrarlo.

Esto es coherente con el comportamiento que instintivamente esperamos: queremos terminar de insertar una copia de los documentos existentes antes de empezar a borrar los antiguos - ¡o puede que no estemos haciendo una copia de todos los documentos originales!

Sentencias DML que devuelven valores

Se puede hacer que las sentencias DML de N1QL devuelvan valores, como en la función siguiente:

Los resultados devueltos se procesan de forma muy similar a los de SELECCIONE declaraciones.

La principal diferencia respecto a las sentencias DML que no devuelven resultados es que cuando no se devuelven resultados, todos los cambios al disco se realizan en cuanto la sentencia devuelve, mientras que cuando se devuelven resultados la sentencia avanza a medida que se recoge cada documento individual del iterador: hay que procesar todos los valores devueltos para que todos los cambios lleguen al disco.

De nuevo, la sentencia se ejecuta de forma asíncrona, por lo que, al recopilar cada resultado individual, no debe asumir que es la última modificación realizada en el disco: podrían haberse realizado más, con los resultados relevantes en cola a la espera de ser recopilados.

Al igual que con las sentencias DML que no devuelven resultados, las que sí lo hacen se ejecutan en serie, lo que significa que si no se procesan todos los resultados en cola en el iterador para cuando se inicie la siguiente sentencia, el jsevaluator completará la sentencia actual descartando todos los valores no procesados.

Conclusión

Hemos cubierto el procesamiento de documentos a través de N1QL y la ejecución de la manipulación de datos.

A continuación, vamos a ver cómo gestionar los errores.

Autor

Publicado por Marco Greco, Arquitecto de software, Couchbase

En su vida anterior, Marco fue director de tecnología, radiofísico, arquitecto de software, administrador de sistemas, administrador de bases de datos, formador y manitas en general en la mayor clínica de radioterapia de Italia. Tras cambiar de carrera y de país, pasó más de dos décadas en varios puestos de soporte y desarrollo en Informix primero e IBM después, antes de finalmente dar el paso y unirse a Couchbase, para ayudarles a convertir N1QL en oro. Es titular de varias patentes y autor de sus propios proyectos de código abierto.

Dejar una respuesta