Cómo leer esta página. Diez pasos, una consulta a la vez. Para cada uno: la consulta a escribir, lo que muestra Neo4j Browser, y qué mirar. Escribe tú mismo cada consulta. Los bloques «Para entender bien» son opcionales. Si el laboratorio no está iniciado o si
etatno dicenœuds : 872, vuelve a la práctica guiada, sección En resumen (kit:https://github.com/hrhouma2/aiopsatlas-recherche-graphes-labo-fr).
En la práctica guiada, contaste 872 nodos y 3712 relaciones cargados por un script, y miraste burbujas y flechas que otra persona había dibujado. Aquí, dibujas las tuyas. Primero un nodo vacío, para ver que un nodo es exactamente eso; luego le das un nombre, una edad, una ciudad; luego un segundo nodo, y una flecha entre ambos; luego una flecha hacia un curso del conjunto de datos real. Al final, el contador de etat sube a 874, y lo devuelves a 872 eliminando lo que creaste, con el error que hay que haber visto una vez para entender qué es una relación.
Un nodo es una burbuja. Una etiqueta dice de qué tipo de burbuja se trata (Personne, Cours, Ville): es el equivalente del nombre de la tabla. Una propiedad es un valor escrito en la burbuja (nom: "Alice", age: 30): una columna. Una relación es una flecha entre dos burbujas; tiene un tipo en mayúsculas (CONNAIT, AIME), un sentido, y puede llevar sus propias propiedades. En SQL, la flecha sería una clave foránea o una tabla de unión; aquí es un objeto de pleno derecho, que creas, lees y eliminas como un nodo.
| Neo4j | Base SQL clásica | En esta práctica |
|---|---|---|
| nodo | fila | Alice, Bob |
| etiqueta | tabla | Personne |
| propiedad | columna | nom, age, ville |
| relación | clave foránea / tabla de unión | CONNAIT, AIME |
| tipo de relación | nombre de la tabla de unión | CONNAIT |
| propiedad de relación | columna de la tabla de unión | depuis: 2024 |
Dos reglas de escritura Cypher para recordar: una burbuja se escribe entre paréntesis (p:Personne), una flecha entre corchetes con un guion y una punta -[:CONNAIT]->. La letra antes de los dos puntos (p, a, r) es un nombre temporal que eliges para reutilizar el objeto en la misma consulta.
Abre http://localhost:7474, conéctate (neo4j / aiopsatlas2026, URL localhost:7687). El editor es la línea neo4j$ en la parte superior. Envías con Ctrl + Enter (Cmd + Enter en macOS) o el botón ▶ a la derecha. Cada consulta abre un recuadro bajo el editor, el más reciente arriba.
Un recuadro muestra dos cosas. Arriba, una línea verde de balance: Created 1 node, added 1 label, Set 1 property, Deleted 2 nodes… Es la que te dice qué cambió la consulta. Debajo, si la consulta tiene un RETURN, el resultado en tres vistas: Graph (las burbujas y las flechas), Table (los valores en columnas), Raw (el JSON en bruto). Una consulta sin RETURN solo muestra el balance y Completed after … ms.
CREATE (p:Personne) RETURN pQué pide la consulta: crea una burbuja con la etiqueta Personne, llámala p durante la consulta, y muéstramela.
Balance: Created 1 node, added 1 label, luego Started streaming 1 record after 1 ms and completed after 2 ms.
A observar: vista Graph, una sola burbuja, y a la derecha en Results overview: Nodes (1) con la pastilla Personne (1). Haz clic en la burbuja: el panel no lista ninguna propiedad. Es un nodo mínimo: una etiqueta, nada más. Equivalente SQL: INSERT INTO personne DEFAULT VALUES, en una tabla que no tendría ninguna columna.
CREATE (n) sin etiqueta, también funciona. Neo4j lo acepta, pero ya no podrías encontrarla salvo recorriendo todas las burbujas del grafo: una fila sin tabla. No lo hagas; una etiqueta, siempre.Personne es una etiqueta nueva en este grafo, que solo conocía cinco (Competence, Cours, Etudiant, Professeur, Ville). No tuviste que declarar nada: la primera burbuja que lleva una etiqueta la crea. Como el mapping de Elasticsearch, en el taller fundamental 1.RETURN p no es obligatorio. Sin él, la consulta crea la burbuja y solo muestra el balance. Está ahí para que la veas.MATCH (p:Personne) SET p.nom = 'Alice' RETURN pQué pide la consulta: encuentra las burbujas Personne (solo hay una), escribe en ella nom = 'Alice', muéstrala.
Balance: Set 1 property.
A observar: la burbuja ahora lleva Alice como leyenda (Browser muestra por defecto la primera propiedad de texto). Haz clic en ella: nom: Alice. Equivalente SQL: UPDATE personne SET nom = 'Alice'.
MATCH antes de SET. Para modificar una burbuja, primero hay que encontrarla. MATCH (p:Personne) es el SELECT … FROM personne; SET es el UPDATE. Cypher encadena ambos en la misma frase.'Alice' (las comillas dobles también funcionan). Los números se escriben sin comillas: 30, no '30'.ville vacía para Bob más adelante: simplemente no tendrá la propiedad ville.MATCH (p:Personne {nom: 'Alice'}) SET p.age = 30, p.ville = 'Montréal' RETURN pQué pide la consulta: encuentra la burbuja Personne cuyo nom es Alice, escribe dos valores más.
Balance: Set 2 properties.
A observar: la burbuja, al hacer clic, muestra nom: Alice, age: 30, ville: Montréal. El {nom: 'Alice'} entre llaves es un filtro: «la que tiene nom igual a Alice», el WHERE nom = 'Alice' de SQL. No cambia nada aquí (una sola Personne), pero desde el siguiente paso se vuelve indispensable.
CREATE (b:Personne {nom: 'Bob', age: 25}) RETURN bQué pide la consulta: crea una burbuja Personne que ya tiene nom y age.
Balance: Created 1 node, set 2 properties, added 1 label.
Mira ahora tus dos burbujas en tabla:
MATCH (p:Personne) RETURN p.nom, p.age, p.villeVista Table:
p.nom p.age p.ville
"Alice" 30 "Montréal"
"Bob" 25 nullA observar: null para la ciudad de Bob: no tiene esa propiedad. En SQL sería una celda vacía de la columna ville; aquí, la casilla no existe en absoluto. Equivalente SQL: SELECT nom, age, ville FROM personne.
MATCH (a:Personne {nom: 'Alice'}), (b:Personne {nom: 'Bob'})
CREATE (a)-[:CONNAIT]->(b)Qué pide la consulta: encuentra a Alice, llámala a; encuentra a Bob, llámalo b; crea una flecha de tipo CONNAIT que parte de a y llega a b.
Balance: Created 1 relationship, luego Completed after … ms. Sin resultado: no hay RETURN.
Mira la flecha:
MATCH (a:Personne)-[r]->(b:Personne) RETURN a, r, bQué pide la consulta: todas las flechas, sea cual sea su tipo ([r] sin :TYPE), que van de una Personne a una Personne.
A observar: vista Graph, dos burbujas y una flecha con CONNAIT escrito encima, en el sentido Alice → Bob. A la derecha, Results overview: Nodes (2), Relationships (1) con la pastilla CONNAIT (1). Equivalente SQL: INSERT INTO connait (personne_source, personne_cible) VALUES (id_alice, id_bob), en una tabla de unión que habrías tenido que crear antes.
MATCH en la primera línea: sin él, CREATE (a)-[:CONNAIT]->(b) crearía dos burbujas nuevas y vacías y una flecha entre ellas. Error clásico._: CONNAIT, A_SUIVI, ENSEIGNE. No es obligatorio, es lo que hace todo el mundo.(a)-[:CONNAIT]->(b): la punta está en b. No existe relación sin dirección en Neo4j; al leer, en cambio, se puede ignorar el sentido (paso 7).MATCH (:Personne {nom: 'Alice'})-[r:CONNAIT]->(:Personne {nom: 'Bob'})
SET r.depuis = 2024
RETURN rQué pide la consulta: encuentra la flecha CONNAIT que va de Alice a Bob, llámala r, escribe en ella depuis = 2024.
Balance: Set 1 property.
Lee todo en tabla:
MATCH (a:Personne)-[r:CONNAIT]->(b:Personne)
RETURN a.nom, type(r), r.depuis, b.noma.nom type(r) r.depuis b.nom
"Alice" "CONNAIT" 2024 "Bob"A observar: type(r) da el tipo de la flecha; r.depuis su propiedad, exactamente como p.nom para una burbuja. Una relación se trata como un nodo: se encuentra, se nombra, se lee y se escribe en ella. Las burbujas sin nombre temporal, (:Personne {…}), son aquellas que no necesitas después: puedes omitir la letra.
MATCH (:Personne {nom: 'Bob'})-[:CONNAIT]->(x) RETURN x.nomQué pide la consulta: ¿a quién conoce Bob? Las burbujas x al final de una flecha CONNAIT que parte de Bob.
(no changes, no records)A observar: cero líneas. La única flecha va de Alice hacia Bob; ninguna parte de Bob. Ahora sin la punta:
MATCH (:Personne {nom: 'Bob'})-[:CONNAIT]-(x) RETURN x.nomx.nom
"Alice"-[:CONNAIT]- sin >: «una flecha CONNAIT entre Bob y x, en un sentido o en el otro». Alice aparece. Recuerda: al escribir, el sentido es obligatorio; al leer, tú eliges tenerlo en cuenta o no. Es lo que hace tan corto de escribir «quién está conectado con quién» en Cypher.
MATCH (a:Personne {nom: 'Alice'}), (c:Cours {id: 'C0001'})
CREATE (a)-[:AIME]->(c)Qué pide la consulta: encuentra a Alice, encuentra el curso C0001 del conjunto de datos, crea una flecha AIME de una hacia el otro.
Balance: Created 1 relationship.
Alice ahora está conectada a una burbuja que existía antes que tú. Mira todo lo que sale de ella:
MATCH (a:Personne {nom: 'Alice'})-[r]->(x)
RETURN a.nom, type(r), labels(x)[0] AS type_cible, coalesce(x.nom, x.titre) AS ciblea.nom type(r) type_cible cible
"Alice" "AIME" "Cours" "Docker expliqué simplement"
"Alice" "CONNAIT" "Personne" "Bob"A observar: dos líneas, dos tipos de flecha, dos tipos de destino. labels(x)[0] da la etiqueta de la burbuja al final; coalesce(x.nom, x.titre) toma nom si existe, si no titre (Bob tiene un nom, el curso tiene un titre). Esta es tu tabla-entregable: guárdala. En SQL, habría hecho falta una unión por tabla de destino y un UNION; aquí, una sola línea de MATCH.
Pasa a la vista Graph con MATCH (a:Personne {nom: 'Alice'})-[r]->(x) RETURN a, r, x: Alice en el centro, Bob a un lado, el curso al otro, en dos colores (uno por etiqueta).
MATCH (n) RETURN count(n) AS noeudsnoeuds
874872 + tus 2 burbujas. Por etiqueta:
MATCH (n) RETURN labels(n)[0] AS label, count(*) ORDER BY labellabel count(*)
"Competence" 22
"Cours" 504
"Etudiant" 300
"Personne" 2
"Professeur" 30
"Ville" 16A observar: una sexta línea, Personne 2. En una terminal, .\labo.ps1 etat o ./labo.sh etat ahora muestra ✔ Neo4j répond — nœuds : 874. El script y Neo4j Browser cuentan lo mismo por dos caminos: es la verificación cruzada de la práctica guiada, aplicada a lo que creaste tú mismo.
Prueba primero la eliminación ingenua:
MATCH (p:Personne) DELETE pNeo.ClientError.Schema.ConstraintValidationFailed
Cannot delete node<874>, because it still has relationships. To delete this node, you must first delete its relationships.A observar: un recuadro rojo, nada eliminado. Neo4j se niega a borrar una burbuja que todavía tiene flechas: una flecha sin burbuja al final no tendría sentido. El número node<874> es el identificador interno de la primera burbuja que intentó eliminar; en tu caso será diferente. Es el equivalente de una violación de clave foránea en SQL, con una diferencia: aquí, el remedio cabe en una palabra.
MATCH (p:Personne) DETACH DELETE pQué pide la consulta: encuentra las burbujas Personne, sepáralas (elimina sus flechas), luego elimínalas.
Balance: Deleted 2 nodes, deleted 2 relationships.
Dos nodos, dos relaciones: CONNAIT y AIME. El curso C0001 no se tocó, solo desapareció la flecha que lo apuntaba. Verifica:
MATCH (n) RETURN count(n) AS noeudsnoeuds
872MATCH (n) RETURN labels(n)[0] AS label, count(*) ORDER BY label vuelve a dar cinco líneas, sin Personne, y etat dice nœuds : 872.
DETACH DELETE es el gesto normal para eliminar un nodo en Neo4j; DELETE solo sirve para un nodo que sabes que está aislado, o para eliminar una relación: MATCH ()-[r:AIME]->() DELETE r borra la flecha y conserva las burbujas.MERGE en lugar de CREATE: «crea si no existe, si no, reutiliza». Es lo que permite que el script charger-graphe se pueda relanzar sin duplicados. Con CREATE, relanzar el paso 4 habría fabricado un segundo Bob.DELETE pratique-mini en el taller fundamental 1. Toma la costumbre: lo que creas para aprender, lo eliminas al final.nom, luego age y ville, con SET, encontrándolo primero con MATCH.null donde falta una propiedad.CONNAIT entre dos burbujas existentes, pusiste depuis en ella, y leíste type(r) y r.depuis en tabla.(Bob)-[:CONNAIT]->(x) no devuelve nada y (Bob)-[:CONNAIT]-(x) devuelve a Alice.C0001 y guardaste la tabla de dos líneas del paso 8 como entregable.Cannot delete node … because it still has relationships, luego DETACH DELETE devolvió Deleted 2 nodes, deleted 2 relationships.MATCH (n) RETURN count(n) y etat dicen 872.Invalid input, expected … en rojo → error de sintaxis. Las tres causas en el aula: un paréntesis ( cerrado con un corchete ], una punta de flecha olvidada al escribir (-[:CONNAIT]- en un CREATE se rechaza: Only directed relationships are supported in CREATE), una comilla faltante alrededor de un texto.Variable `r` not defined (o a, p…) → usas una letra en SET o RETURN que ningún MATCH ni CREATE de la misma consulta introdujo. Ejemplo: SET r.depuis = 2024 mientras que la flecha se escribió -[:CONNAIT]-> sin la r. Añade la letra donde aparece el objeto: -[r:CONNAIT]->.Created 2 nodes, created 1 relationship, y Results overview muestra * (4)) → escribiste CREATE (a)-[:CONNAIT]->(b) sin el MATCH justo antes, o con un punto y coma entre las dos líneas. a y b eran desconocidos: Neo4j no protesta, los inventa, sin etiqueta ni propiedad. Limpia: MATCH (n) WHERE size(labels(n)) = 0 DETACH DELETE n, luego repite el paso 5 en una sola consulta.MATCH (p:Personne) RETURN count(p) devuelve más de 2) → relanzaste un CREATE. MATCH (p:Personne) DETACH DELETE p y repite desde el paso 1; el módulo 6 te enseñará MERGE, que evita esto.Cannot delete node … because it still has relationships → es el paso 10, buscado. DETACH DELETE.<id> en lugar de Alice → Browser todavía no sabe qué propiedad mostrar. Haz clic en la pastilla Personne bajo el grafo y elige nom como leyenda; o lee en vista Table.etat sigue diciendo nœuds : 872 después de tus creaciones → estás conectado a otra base u otro Neo4j (¿un neo4j instalado localmente en el puerto 7687?). En Browser, la banda superior debe decir neo4j://localhost:7687 y Database: neo4j; si no, cierra el otro Neo4j o cambia su puerto.Neo.ClientError.Security.Unauthorized → contraseña rechazada. Es aiopsatlas2026; si la cambiaste y la perdiste, ./labo.sh reinitialiser luego demarrer y charger-graphe (los datos del kit se recargan de forma idéntica).