Consultar los datos con AQL

En este capítulo, discutiremos cómo consultar los datos con AQL. Ya hemos comentado en nuestros capítulos anteriores que ArangoDB ha desarrollado su propio lenguaje de consulta y que se conoce con el nombre de AQL.

Empecemos ahora a interactuar con AQL. Como se muestra en la imagen a continuación, en la interfaz web, presione elAQL Editorpestaña ubicada en la parte superior de la barra de navegación. Aparecerá un editor de consultas en blanco.

Cuando sea necesario, puede cambiar al editor desde la vista de resultados y viceversa, haciendo clic en las pestañas Consulta o Resultado en la esquina superior derecha como se muestra en la imagen a continuación:

Entre otras cosas, el editor tiene resaltado de sintaxis, funcionalidad de deshacer / rehacer y guardar consultas. Para una referencia detallada, se puede consultar la documentación oficial. Destacaremos algunas características básicas y de uso común del editor de consultas AQL.

Fundamentos de AQL

En AQL, una consulta representa el resultado final que se debe lograr, pero no el proceso mediante el cual se logra el resultado final. Esta característica se conoce comúnmente como propiedad declarativa del lenguaje. Además, AQL puede consultar y modificar los datos, por lo que se pueden crear consultas complejas combinando ambos procesos.

Tenga en cuenta que AQL es totalmente compatible con ACID. La lectura o modificación de consultas concluirá en su totalidad o no concluirá en absoluto. Incluso la lectura de los datos de un documento terminará con una unidad coherente de los datos.

Agregamos dos nuevos songsa la colección de canciones que ya hemos creado. En lugar de escribir, puede copiar la siguiente consulta y pegarla en el editor AQL:

FOR song IN [
   {
      title: "Air-Minded Executive", lyricist: "Johnny Mercer",
      composer: "Bernie Hanighen", Year: 1940, _key: "Air-Minded"
   },
   
   {
      title: "All Mucked Up", lyricist: "Johnny Mercer", composer:
      "Andre Previn", Year: 1974, _key: "All_Mucked"
   }
]
INSERT song IN songs

Presione el botón Ejecutar en la parte inferior izquierda.

Escribirá dos nuevos documentos en el songs colección.

Esta consulta describe cómo funciona el bucle FOR en AQL; itera sobre la lista de documentos codificados JSON, realizando las operaciones codificadas en cada uno de los documentos de la colección. Las diferentes operaciones pueden ser crear nuevas estructuras, filtrar, seleccionar documentos, modificar o insertar documentos en la base de datos (consulte el ejemplo instantáneo). En esencia, AQL puede realizar las operaciones CRUD de manera eficiente.

Para encontrar todas las canciones en nuestra base de datos, ejecutemos una vez más la siguiente consulta, equivalente a un SELECT * FROM songs de una base de datos de tipo SQL (debido a que el editor memoriza la última consulta, presione la *New* botón para limpiar el editor) -

FOR song IN songs
RETURN song

El conjunto de resultados mostrará la lista de canciones guardadas hasta ahora en el songs colección como se muestra en la captura de pantalla a continuación.

Operaciones como FILTER, SORT y LIMIT se puede agregar al For loop cuerpo para estrechar y ordenar el resultado.

FOR song IN songs
FILTER song.Year > 1940
RETURN song

La consulta anterior dará canciones creadas después del año 1940 en la pestaña Resultado (ver la imagen a continuación).

En este ejemplo se utiliza la clave del documento, pero también se puede utilizar cualquier otro atributo como equivalente para el filtrado. Dado que se garantiza que la clave del documento es única, no más de un documento coincidirá con este filtro. Para otros atributos, este puede no ser el caso. Para devolver un subconjunto de usuarios activos (determinado por un atributo llamado estado), ordenados por nombre en orden ascendente, usamos la siguiente sintaxis:

FOR song IN songs
FILTER song.Year > 1940
SORT song.composer
RETURN song
LIMIT 2

Hemos incluido deliberadamente este ejemplo. Aquí, observamos un mensaje de error de sintaxis de consulta resaltado en rojo por AQL. Esta sintaxis resalta los errores y es útil para depurar sus consultas como se muestra en la captura de pantalla a continuación.

Ejecutemos ahora la consulta correcta (observe la corrección) -

FOR song IN songs
FILTER song.Year > 1940
SORT song.composer
LIMIT 2
RETURN song

Consulta compleja en AQL

AQL está equipado con múltiples funciones para todos los tipos de datos admitidos. La asignación de variables dentro de una consulta permite construir construcciones anidadas muy complejas. De esta manera, las operaciones con uso intensivo de datos se acercan más a los datos en el backend que al cliente (como el navegador). Para entender esto, primero agreguemos las duraciones arbitrarias (longitud) a las canciones.

Comencemos con la primera función, es decir, la función Actualizar -

UPDATE { _key: "All_Mucked" }
WITH { length: 180 }
IN songs

Podemos ver que se ha escrito un documento como se muestra en la captura de pantalla anterior.

Actualicemos ahora también otros documentos (canciones).

UPDATE { _key: "Affable_Balding" }
WITH { length: 200 }
IN songs

Ahora podemos comprobar que todas nuestras canciones tienen un nuevo atributo length -

FOR song IN songs
RETURN song

Salida

[
   {
      "_key": "Air-Minded",
      "_id": "songs/Air-Minded",
      "_rev": "_VkC5lbS---",
      "title": "Air-Minded Executive",
      "lyricist": "Johnny Mercer",
      "composer": "Bernie Hanighen",
      "Year": 1940,
      "length": 210
   },
   
   {
      "_key": "Affable_Balding",
      "_id": "songs/Affable_Balding",
      "_rev": "_VkC4eM2---",
      "title": "Affable Balding Me",
      "lyricist": "Johnny Mercer",
      "composer": "Robert Emmett Dolan",
      "Year": 1950,
      "length": 200
   },
   
   {
      "_key": "All_Mucked",
      "_id": "songs/All_Mucked",
      "_rev": "_Vjah9Pu---",
      "title": "All Mucked Up",
      "lyricist": "Johnny Mercer",
      "composer": "Andre Previn",
      "Year": 1974,
      "length": 180
   },
   
   {
      "_key": "Accentchuate_The",
      "_id": "songs/Accentchuate_The",
      "_rev": "_VkC3WzW---",
      "title": "Accentchuate The Politics",
      "lyricist": "Johnny Mercer",
      "composer": "Harold Arlen",
      "Year": 1944,
      "length": 190
   }
]

Para ilustrar el uso de otras palabras clave de AQL como LET, FILTER, SORT, etc., ahora formateamos las duraciones de la canción en el mm:ss formato.

Consulta

FOR song IN songs
FILTER song.length > 150
LET seconds = song.length % 60
LET minutes = FLOOR(song.length / 60)
SORT song.composer
RETURN
{
   Title: song.title, 
   Composer: song.composer, 
   Duration: CONCAT_SEPARATOR(':',minutes, seconds) 
}

Esta vez devolveremos el título de la canción junto con la duración. losReturn La función le permite crear un nuevo objeto JSON para devolver por cada documento de entrada.

Ahora hablaremos sobre la función 'Uniones' de la base de datos AQL.

Empecemos por crear una colección. composer_dob. Además, crearemos los cuatro documentos con la fecha hipotética de nacimiento de los compositores ejecutando la siguiente consulta en el cuadro de consulta:

FOR dob IN [
   {composer: "Bernie Hanighen", Year: 1909}
   ,
   {composer: "Robert Emmett Dolan", Year: 1922}
   ,
   {composer: "Andre Previn", Year: 1943}
   ,
   {composer: "Harold Arlen", Year: 1910}
]
INSERT dob in composer_dob

Para resaltar la similitud con SQL, presentamos una consulta de bucle FOR anidada en AQL, que conduce a la operación REPLACE, iterando primero en el bucle interno, sobre la documentación de todos los compositores y luego sobre todas las canciones asociadas, creando un nuevo documento que atributo song_with_composer_key en vez de song atributo.

Aquí va la consulta:

FOR s IN songs
FOR c IN composer_dob
FILTER s.composer == c.composer

LET song_with_composer_key = MERGE(
   UNSET(s, 'composer'),
   {composer_key:c._key}
)
REPLACE s with song_with_composer_key IN songs

Ejecutemos ahora la consulta FOR song IN songs RETURN song nuevamente para ver cómo ha cambiado la colección de canciones.

Salida

[
   {
      "_key": "Air-Minded",
      "_id": "songs/Air-Minded",
      "_rev": "_Vk8kFoK---",
      "Year": 1940,
      "composer_key": "5501",
      "length": 210,
      "lyricist": "Johnny Mercer",
      "title": "Air-Minded Executive"
   },
   
   {
      "_key": "Affable_Balding",
      "_id": "songs/Affable_Balding",
      "_rev": "_Vk8kFoK--_",
      "Year": 1950,
      "composer_key": "5505",
      "length": 200,
      "lyricist": "Johnny Mercer",
      "title": "Affable Balding Me"
   },
   
   {
      "_key": "All_Mucked",
      "_id": "songs/All_Mucked",
      "_rev": "_Vk8kFoK--A",
      "Year": 1974,
      "composer_key": "5507",
      "length": 180,
      "lyricist": "Johnny Mercer",
      "title": "All Mucked Up"
   },
   
   {
      "_key": "Accentchuate_The",
      "_id": "songs/Accentchuate_The",
      "_rev": "_Vk8kFoK--B",
      "Year": 1944,
      "composer_key": "5509",
      "length": 190,
      "lyricist": "Johnny Mercer",
      "title": "Accentchuate The Politics"
   }
]

La consulta anterior completa el proceso de migración de datos, agregando el composer_key a cada canción.

Ahora la siguiente consulta es nuevamente una consulta de bucle FOR anidada, pero esta vez conduce a la operación Unir, agregando el nombre del compositor asociado (escogiendo con la ayuda de `composer_key`) a cada canción -

FOR s IN songs
FOR c IN composer_dob
FILTER c._key == s.composer_key
RETURN MERGE(s,
{ composer: c.composer }
)

Salida

[
   {
      "Year": 1940,
      "_id": "songs/Air-Minded",
      "_key": "Air-Minded",
      "_rev": "_Vk8kFoK---",
      "composer_key": "5501",
      "length": 210,
      "lyricist": "Johnny Mercer",
      "title": "Air-Minded Executive",
      "composer": "Bernie Hanighen"
   },
   
   {
      "Year": 1950,
      "_id": "songs/Affable_Balding",
      "_key": "Affable_Balding",
      "_rev": "_Vk8kFoK--_",
      "composer_key": "5505",
      "length": 200,
      "lyricist": "Johnny Mercer",
      "title": "Affable Balding Me",
      "composer": "Robert Emmett Dolan"
   },

   {
      "Year": 1974,
      "_id": "songs/All_Mucked",
      "_key": "All_Mucked",
      "_rev": "_Vk8kFoK--A",
      "composer_key": "5507",
      "length": 180,
      "lyricist": "Johnny Mercer",
      "title": "All Mucked Up",
      "composer": "Andre Previn"
   },

   {
      "Year": 1944,
      "_id": "songs/Accentchuate_The",
      "_key": "Accentchuate_The",
      "_rev": "_Vk8kFoK--B",
      "composer_key": "5509",
      "length": 190,
      "lyricist": "Johnny Mercer",
      "title": "Accentchuate The Politics",
      "composer": "Harold Arlen"
   }
]