Introducción a Cypher

Ahora que ya conocemos las características de las bases de datos NoSQL en grafo, y tenemos Neo4j instalado y funcionando, es el momento de empezar con Cypher.

Cypher es un lenguaje declarativo, inspirado en SQL, que permite manipular datos en Neo4j. Es aconsejable tener a mano la guía de referencia de Cypher siempre que estemos trabajando con Neo4j. Esta guía recoge la sintaxis y la semántica de las sentencias y funciones disponibles en Cypher. Hay que tener en cuenta que existe una guía de referencia (refcard) para cada versión de Neo4j (nosotros hemos elegido la guía de referencia para Neo4j versión 3.4).

Antes de continuar os animamos a que abráis el browser de la base de datos que creamos en la segunda entrada. En el siguiente vídeo mostramos cómo abrir el browser y explicamos los elementos básicos del entorno de trabajo de Neo4j.

 

 

Ahora que ya conocemos la interfaz es el momento de empezar a trabajar con datos. Lo primero que vamos a hacer es aprender a crear nodos y relaciones en Neo4j. Para ello tendremos que usar la cláusula CREATE. Por ejemplo, empezamos ejecutando la siguiente sentencia:

¿Qué es lo que se ha creado? Podemos averiguarlo mediante la siguiente consulta:

La sentencia anterior nos devuelve todos los nodos de la base de datos. En este caso nos ha devuelto un nodo, el que acabamos de crear. Pero, ¿qué información tiene ese nodo? Pues la verdad es que ninguna, es un nodo vacío. Sin tipo y sin propiedades (o atributos). Un nodo sin información por lo general no tiene mucho sentido, por lo que vamos a aprender cómo añadir atributos (propiedades) a un nuevo nodo.

Para añadir un conjunto de propiedades a un nuevo nodo, se indica el conjunto de propiedades y sus valores en formato JSON. Por lo tanto, si quisiéramos crear un nodo para almacenar los datos de Jordi Conesa, deberíamos incluir en la definición del nodo los siguientes atributos y valores:

Ahora crearemos un nodo con esta información asociada.

Una vez creado, si volvemos a ejecutar la sentencia:

Obtendremos los dos nodos creados hasta ahora. Puede parecer que los dos nodos son iguales, pero no es así. Si hacéis click en uno de los nodos (como en la siguiente figura), veréis que uno de ellos contiene algunas propiedades (ver la parte inferior izquierda de la pantalla). El otro nodo, en cambio, está vacío.

Ahora crearemos un nodo con la siguiente información asociada:

Pero, ¿cómo podemos indicar a Neo4j que queremos que nos muestre por pantalla el nodo que acabamos de crear? La manera de hacerlo es mediante variables. En Cypher, se pueden utilizar variables para identificar los elementos que aparecen en las cláusulas CREATE. Si queremos mostrar por pantalla alguno de los nodos que aparece en la cláusula CREATE, podemos asignarle un nombre de variable y luego referenciar esa variable en una cláusula RETURN. Las variables se asignan a los nodos indicando un nombre de variable antes de la definición de sus propiedades. En la siguiente sentencia definimos la variable p en la sentencia CREATE. Después, al hacer un RETURN p, estamos indicando a Neo4j que el nodo a mostrar es el que contiene los datos que acabamos de crear. Probad a ejecutar la siguiente sentencia:

Si hacéis click sobre el nodo resultante, veréis que tiene los datos de María Elena.

El uso de variables en Cypher es necesario cuando hay que utilizar los datos que definimos en la cláusula CREATE en otra parte de la sentencia. En ejemplo previo, si os fijáis, necesitamos referenciar el nodo que estamos creando en la cláusula RETURN (con el objetivo de consultarlo), de aquí la necesidad de usar la variable p.

Bien, ya sabemos crear nodos, pero ¿cuál es el tipo de los nodos? Vaya, no lo sabemos. No hemos indicado el tipo de los nodos cuando los hemos creado… Eso quiere decir que los nodos creados no tienen ningún tipo, es decir, carecen de semántica (o si preferís, carecen de significado). Si pobláramos de esta manera la base de datos, no tendríamos manera de saber qué personas hay en la base de datos. La pregunta es ¿cómo creamos un nodo con tipo?

Muy fácil, hay que indicar el tipo del nodo en la cláusula CREATE antes de sus propiedades (en caso de que haya) y después de su variable (en caso de que se haya indicado). Vamos a crear un nuevo nodo para Jordi Conesa pero, en este caso, indicando que Jordi Conesa es una persona:

La sentencia anterior crea un nodo de tipo persona (:Person) con las propiedades name, age y city. Tal y como comentamos en la anterior entrada, los nombres de etiqueta siempre tienen “:” como prefijo en Cypher.

Si observamos el nodo devuelto por Neo4j, vemos que el formato es más atractivo con un color asociado a su tipo. En la parte superior izquierda se puede ver el nombre de la etiqueta. Si hacemos click encima de dicha etiqueta podemos cambiar el color y el tamaño de los nodos de ese tipo y también qué propiedad queremos utilizar como caption (el valor que se muestra dentro de los nodos). A continuación podéis ver el nodo original y el nodo después de cambiar su color y tamaño.

Como podéis imaginar, el hecho de cambiar el color, el tamaño y el caption de los nodos es meramente estético, pero ayuda a la interpretación de los datos, especialmente a medida que la base de datos se hace más y más compleja.

Si quisiéramos crear más de un nodo, podríamos añadir los distintos nodos a crear dentro de una misma cláusula CREATE, separados por comas. Por ejemplo, en la siguiente sentencia se crean dos nodos (uno para María Elena Rodríguez y uno para la editorial Auca Digital) y una relación entre ellos para indicar que a María Elena le gustan los libros de Auca Digital.

Podemos ver que la cláusula CREATE tiene tres elementos, con los siguientes nombres de variable er (para el nodo de María Elena), ad (para el nodo de Auca Digital) y un tercer elemento que tiene la forma (er)-[:LIKES]->(ad).

Cypher intenta representar textualmente patrones gráficos que nos encontramos en los grafos. Por ejemplo, en Cypher se podría representar que un nodo a está relacionado con un nodo mediante el siguiente texto: (a)–(b). En este caso se indica que hay dos nodos relacionados (si preferís, conectados a través de una relación), pero no se indica ni el sentido ni el tipo de la relación. Si queremos indicar el sentido de la relación podemos poner un < o un > en uno de sus extremos. Así, tendríamos que (a)–>(b) indica que hay una relación que va de a a b y (a)<–(b) indica que hay una relación que va de b a a. Si queremos, además, indicar que la relación debe ser de un tipo concreto, tenemos que poner su tipo entre corchetes [] dentro de la relación. Por ejemplo (a)-[:LIKES]-(b) indicaría que hay una relación de tipo LIKES que va de a a b.

Teniendo en cuenta lo que acabamos de explicar, puede verse que el tercer elemento ─(er)-[:LIKES]->(ad) de nuestra sentencia CREATE, indica que debe haber una relación de tipo LIKES que va del nodo de María Elena Rodríguez (porque a la izquierda de la relación hay la variable del nodo de María Elena) al nodo de Auca Digital (ya que a la derecha de la relación hay la variable del nodo Auca Digital). Como este elemento está en una cláusula CREATE, estamos diciendo que queremos crear esta relación entre los dos nodos. Como consecuencia, se crearía el nodo de María Elena, el nodo de Auca Digital y la relación LIKES, tal y como se ve en la siguiente figura:

Como se ve en la figura, el resultado muestra los nodos y la relación creada. Quizás os preguntéis por qué se muestra la relación si en la cláusula RETURN sólo se referenciaban los nodos creados. El hecho es que el entorno de Neo4j, por defecto, cuando muestra un conjunto de nodos “pinta” todas las relaciones que hay entre estos nodos automáticamente.

Pues bien, ya somos capaces de añadir nodos y relaciones en Cypher. Ahora os proponemos un reto. La sentencia que os indicamos a continuación añade un nodo para Jordi, otro para María Elena, otro para una entrada del blog de Informática++, y relaciones que indican que Jordi y María Elena han escrito una determinada entrada. Os pedimos que cambiéis los <…> (marcados en negrita en la sentencia suministrada) por fragmentos en Cypher para añadir un nodo que os describa (como :Person), y una relación que indique que habéis leído la entrada con variable myPost. Además, deberéis añadir un nombre de variable en la cláusula RETURN para devolver el nodo creado (el nodo que os representa).

En el caso de que os resulte difícil, os animamos a estudiar atentamente la sentencia de ejemplo que había al final de la entrada anterior. Facilitará mucho las cosas 😉

Hasta aquí esta tercera entrada sobre Neo4j. En ella hemos aprendido cómo crear nodos y relaciones entre nodos en Cypher. Con lo que hemos visto hasta ahora, cuando queramos crear una relación deberemos crear a la vez los nodos. Para crear relaciones sobre nodos que ya existen en la base de datos deberéis esperar hasta la siguiente entrada, ya que para ello hace falta conocer cómo funcionan las consultas. Y las consultas las trataremos la próxima semana.

En el caso de que queráis obtener más información e ir avanzando, podéis visualizar el siguiente vídeo. Una vez sepamos cómo realizar consultas, cargaremos una base de datos de películas proporcionada en Neo4j y aprenderemos a realizar consultas más complejas y de forma eficiente.

 

Jordi Conesa es profesor de los Estudios de Informática, Multimedia y Telecomunicación en la UOC y coordinador del ámbito de data science del eHealth Center. Su docencia se enfoca a las áreas de bases de datos, ciencia de datos e ingeniería del software y su investigación en el análisis de datos y el eLearning.

M. Elena Rodríguez es profesora de los Estudios de Informática, Multimedia y Telecomunicación de la UOC y forma parte del proyecto TeSLA, participando en tareas que se centran en el diseño del sistema TeSLA y en el desarrollo de pruebas piloto en la UOC. Licenciada en Informática por la Universitat Politècnica de Catalunya y doctora por la Universidad de Alcalá, sus áreas de conocimiento e investigación incluyen las bases de datos y la ingeniería de ontologías para el desarrollo de sistemas de e-learning basados en estándares.

Comentar

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Leer entrada anterior
Introducción a Neo4j

Ahora que ya conocemos las principales características de las bases de datos NoSQL en grafo y del modelo de datos...

Cerrar