Ερευνητικό εργαστήριο 2 — Neo4j: κόμβος, ιδιότητες, σχέση

Καθοδηγούμενη πρακτική15 λεπτά
Διάρκεια
25 λεπτά
Ενότητα
1/7
Προαπαιτούμενα
το εργαστήριο τρέχει (η etat δείχνει κόμβοι: 872), το Neo4j Browser ανοιχτό και συνδεδεμένο
Θα φτιάξεις
δύο δικούς σου κόμβους, την Alice και τον Bob, ενωμένους με ένα βέλος, μετά ενωμένους με τον πραγματικό γράφο του μαθήματος, πριν σβήσεις τα πάντα καθαρά
Παραδοτέο
ο πίνακας του βήματος 8 (Alice, οι δύο σχέσεις της, οι στόχοι τους)

Πώς να διαβάσεις αυτή τη σελίδα. Δέκα βήματα, ένα ερώτημα τη φορά. Για κάθε ένα: το ερώτημα που πληκτρολογείς, τι εμφανίζει το Neo4j Browser, και τι πρέπει να προσέξεις. Πληκτρολόγησε μόνος σου κάθε ερώτημα. Τα πλαίσια «Για να κατανοήσεις καλά» είναι προαιρετικά. Αν το εργαστήριο δεν έχει ξεκινήσει ή αν η etat δεν λέει κόμβοι: 872, γύρνα στην καθοδηγούμενη πρακτική, ενότητα Εν συντομία (kit: https://github.com/hrhouma2/aiopsatlas-recherche-graphes-labo-fr).

Στόχος

Στην καθοδηγούμενη πρακτική, μέτρησες 872 κόμβους και 3.712 σχέσεις φορτωμένους από ένα σενάριο, και κοίταξες φυσαλίδες και βέλη που κάποιος άλλος είχε σχεδιάσει. Εδώ σχεδιάζεις τα δικά σου. Ένας άδειος κόμβος πρώτα, για να δεις ότι ένας κόμβος είναι ακριβώς αυτό· μετά του δίνεις ένα όνομα, μια ηλικία, μια πόλη· μετά έναν δεύτερο κόμβο, και ένα βέλος ανάμεσα στους δύο· μετά ένα βέλος προς ένα μάθημα από το πραγματικό σύνολο δεδομένων. Στο τέλος, ο μετρητής της etat ανεβαίνει στο 874, και τον επαναφέρεις στο 872 διαγράφοντας ό,τι δημιούργησες, με το σφάλμα που πρέπει να έχεις δει μία φορά για να καταλάβεις τι είναι μια σχέση.

Το λεξιλόγιο σε μία εικόνα

Ένας κόμβος είναι μια φυσαλίδα. Μια ετικέτα λέει τι είδους φυσαλίδα είναι (Personne, Cours, Ville): είναι το ισοδύναμο του ονόματος του πίνακα. Μια ιδιότητα είναι μια τιμή γραμμένη μέσα στη φυσαλίδα (nom: "Alice", age: 30): μια στήλη. Μια σχέση είναι ένα βέλος ανάμεσα σε δύο φυσαλίδες· έχει έναν τύπο με κεφαλαία (CONNAIT, AIME), μια κατεύθυνση, και μπορεί να έχει τις δικές της ιδιότητες. Σε SQL, το βέλος θα ήταν ένα ξένο κλειδί ή ένας πίνακας σύνδεσης· εδώ είναι ένα ανεξάρτητο αντικείμενο, που δημιουργείς, διαβάζεις και διαγράφεις όπως έναν κόμβο.

Neo4jΚλασική βάση SQLΣε αυτή την πρακτική
κόμβοςγραμμήAlice, Bob
ετικέταπίνακαςPersonne
ιδιότηταστήληnom, age, ville
σχέσηξένο κλειδί / πίνακας σύνδεσηςCONNAIT, AIME
τύπος σχέσηςόνομα του πίνακα σύνδεσηςCONNAIT
ιδιότητα σχέσηςστήλη του πίνακα σύνδεσηςdepuis: 2024

Δύο κανόνες γραφής Cypher για να θυμάσαι: μια φυσαλίδα γράφεται μέσα σε παρενθέσεις (p:Personne), ένα βέλος μέσα σε αγκύλες με μια παύλα και μια αιχμή -[:CONNAIT]->. Το γράμμα πριν από τις άνω-κάτω τελείες (p, a, r) είναι ένα προσωρινό όνομα που επιλέγεις για να επαναχρησιμοποιήσεις το αντικείμενο μέσα στο ίδιο ερώτημα.

Πού πληκτρολογείς, και πώς να διαβάσεις την απάντηση

Άνοιξε το http://localhost:7474, συνδέσου (neo4j / aiopsatlas2026, URL localhost:7687). Ο επεξεργαστής είναι η γραμμή neo4j$ πάνω. Στέλνεις με Ctrl + Enter (Cmd + Enter σε macOS) ή το κουμπί ▶ δεξιά. Κάθε ερώτημα ανοίγει ένα πλαίσιο κάτω από τον επεξεργαστή, το πιο πρόσφατο πάνω.

Ένα πλαίσιο εμφανίζει δύο πράγματα. Πάνω, μια πράσινη γραμμή απολογισμού: Created 1 node, added 1 label, Set 1 property, Deleted 2 nodes… Αυτή σου λέει τι άλλαξε το ερώτημα. Από κάτω, αν το ερώτημα έχει RETURN, το αποτέλεσμα σε τρεις προβολές: Graph (οι φυσαλίδες και τα βέλη), Table (οι τιμές σε στήλες), Raw (το ακατέργαστο JSON). Ένα ερώτημα χωρίς RETURN εμφανίζει μόνο τον απολογισμό και Completed after … ms.

Βήμα 1 — Δημιουργία ενός κόμβου, μόνο μια ετικέτα

cypher
CREATE (p:Personne) RETURN p

Τι ζητάει το ερώτημα: δημιούργησε μια φυσαλίδα με την ετικέτα Personne, ονόμασέ την p για τη διάρκεια του ερωτήματος, και δείξε τη μου.

Απολογισμός: Created 1 node, added 1 label, μετά Started streaming 1 record after 1 ms and completed after 2 ms.

Τι να προσέξεις: προβολή Graph, μία μόνο φυσαλίδα, και δεξιά στο Results overview: Nodes (1) με το σήμα Personne (1). Κάνε κλικ στη φυσαλίδα: το πλαίσιο δεν απαριθμεί καμία ιδιότητα. Είναι ένας ελάχιστος κόμβος: μια ετικέτα, τίποτα άλλο. Ισοδύναμο SQL: INSERT INTO personne DEFAULT VALUES, σε έναν πίνακα που δεν θα είχε καμία στήλη.

Για να κατανοήσεις καλά
  • Ακόμα πιο ελάχιστο, το CREATE (n) χωρίς ετικέτα, δουλεύει επίσης. Το Neo4j το δέχεται, αλλά δεν θα μπορούσες πια να το ξαναβρείς παρά περνώντας από όλες τις φυσαλίδες του γράφου: μια γραμμή χωρίς πίνακα. Μην το κάνεις· μια ετικέτα, πάντα.
  • Η Personne είναι μια νέα ετικέτα σε αυτόν τον γράφο, που γνώριζε μόνο πέντε (Competence, Cours, Etudiant, Professeur, Ville). Δεν χρειάστηκε να δηλώσεις τίποτα: η πρώτη φυσαλίδα που φέρει μια ετικέτα τη δημιουργεί. Όπως το mapping του Elasticsearch, στο ερευνητικό εργαστήριο 1.
  • Το RETURN p δεν είναι υποχρεωτικό. Χωρίς αυτό, το ερώτημα δημιουργεί τη φυσαλίδα και εμφανίζει μόνο τον απολογισμό. Είναι εκεί για να τη δεις.

Βήμα 2 — Να της δώσεις μια τιμή

cypher
MATCH (p:Personne) SET p.nom = 'Alice' RETURN p

Τι ζητάει το ερώτημα: βρες τις φυσαλίδες Personne (υπάρχει μόνο μία), γράψε μέσα nom = 'Alice', δείξ' τη.

Απολογισμός: Set 1 property.

Τι να προσέξεις: η φυσαλίδα φέρει τώρα Alice ως λεζάντα (το Browser εμφανίζει από προεπιλογή την πρώτη ιδιότητα κειμένου). Κάνε κλικ πάνω της: nom: Alice. Ισοδύναμο SQL: UPDATE personne SET nom = 'Alice'.

Για να κατανοήσεις καλά
  • MATCH πριν από SET. Για να τροποποιήσεις μια φυσαλίδα, πρέπει πρώτα να τη βρεις. Το MATCH (p:Personne) είναι το SELECT … FROM personne· το SET είναι το UPDATE. Το Cypher συνδέει τα δύο στην ίδια πρόταση.
  • Τα κείμενα γράφονται μέσα σε μονά εισαγωγικά 'Alice' (τα διπλά εισαγωγικά δουλεύουν επίσης). Οι αριθμοί γράφονται χωρίς εισαγωγικά: 30, όχι '30'.
  • Μια ιδιότητα υπάρχει μόνο αν έχει τιμή. Δεν υπάρχει κενή στήλη nom στον Bob σε λίγο: απλώς δεν θα έχει ιδιότητα ville.

Βήμα 3 — Πολλές τιμές μαζί

cypher
MATCH (p:Personne {nom: 'Alice'}) SET p.age = 30, p.ville = 'Montréal' RETURN p

Τι ζητάει το ερώτημα: βρες τη φυσαλίδα Personne της οποίας το nom είναι Alice, γράψε δύο ακόμα τιμές.

Απολογισμός: Set 2 properties.

Τι να προσέξεις: η φυσαλίδα, με κλικ, δείχνει nom: Alice, age: 30, ville: Montréal. Το {nom: 'Alice'} μέσα σε άγκιστρα είναι ένα φίλτρο: «αυτή της οποίας το nom ισούται με Alice», το WHERE nom = 'Alice' της SQL. Δεν αλλάζει τίποτα εδώ (μία μόνο Personne), αλλά από το επόμενο βήμα γίνεται απαραίτητο.

Βήμα 4 — Δημιουργία κόμβου με τις τιμές του μαζί

cypher
CREATE (b:Personne {nom: 'Bob', age: 25}) RETURN b

Τι ζητάει το ερώτημα: δημιούργησε μια φυσαλίδα Personne που έχει αμέσως nom και age.

Απολογισμός: Created 1 node, set 2 properties, added 1 label.

Δες τώρα τις δύο φυσαλίδες σου σε πίνακα:

cypher
MATCH (p:Personne) RETURN p.nom, p.age, p.ville

Προβολή Table:

text
p.nom    p.age  p.ville
"Alice"  30     "Montréal"
"Bob"    25     null

Τι να προσέξεις: null για την πόλη του Bob: δεν έχει αυτή την ιδιότητα. Σε SQL θα ήταν ένα κενό κελί της στήλης ville· εδώ, το κελί δεν υπάρχει καθόλου. Ισοδύναμο SQL: SELECT nom, age, ville FROM personne.

Βήμα 5 — Σύνδεση της Alice με τον Bob

cypher
MATCH (a:Personne {nom: 'Alice'}), (b:Personne {nom: 'Bob'})
CREATE (a)-[:CONNAIT]->(b)

Τι ζητάει το ερώτημα: βρες την Alice, ονόμασέ την a· βρες τον Bob, ονόμασέ τον b· δημιούργησε ένα βέλος τύπου CONNAIT που ξεκινάει από το a και φτάνει στο b.

Απολογισμός: Created 1 relationship, μετά Completed after … ms. Χωρίς αποτέλεσμα: δεν υπάρχει RETURN.

Δες το βέλος:

cypher
MATCH (a:Personne)-[r]->(b:Personne) RETURN a, r, b

Τι ζητάει το ερώτημα: όλα τα βέλη, όποιου τύπου κι αν είναι ([r] χωρίς :TYPE), που πηγαίνουν από μια Personne σε μια Personne.

Τι να προσέξεις: προβολή Graph, δύο φυσαλίδες και ένα βέλος με το CONNAIT γραμμένο πάνω του, στην κατεύθυνση Alice → Bob. Δεξιά, Results overview: Nodes (2), Relationships (1) με το σήμα CONNAIT (1). Ισοδύναμο SQL: INSERT INTO connait (personne_source, personne_cible) VALUES (id_alice, id_bob), σε έναν πίνακα σύνδεσης που θα έπρεπε να είχες δημιουργήσει πριν.

Για να κατανοήσεις καλά
  • Μια σχέση συνδέει δύο φυσαλίδες που ήδη υπάρχουν. Εξ ου και το MATCH στην πρώτη γραμμή: χωρίς αυτό, το CREATE (a)-[:CONNAIT]->(b) θα δημιουργούσε δύο νέες, άδειες φυσαλίδες και ένα βέλος ανάμεσά τους. Κλασικό λάθος.
  • Ο τύπος γράφεται με ΚΕΦΑΛΑΙΑ κατά σύμβαση, με _: CONNAIT, A_SUIVI, ENSEIGNE. Δεν είναι υποχρεωτικό, είναι αυτό που κάνει ο κόσμος.
  • Μια σχέση έχει πάντα κατεύθυνση. (a)-[:CONNAIT]->(b): η αιχμή είναι πάνω στο b. Δεν υπάρχει σχέση χωρίς κατεύθυνση στο Neo4j· στην ανάγνωση, όμως, μπορείς να αγνοήσεις την κατεύθυνση (βήμα 7).

Βήμα 6 — Μια τιμή στο βέλος

cypher
MATCH (:Personne {nom: 'Alice'})-[r:CONNAIT]->(:Personne {nom: 'Bob'})
SET r.depuis = 2024
RETURN r

Τι ζητάει το ερώτημα: βρες το βέλος CONNAIT που πηγαίνει από την Alice στον Bob, ονόμασέ το r, γράψε πάνω του depuis = 2024.

Απολογισμός: Set 1 property.

Διάβασε τα όλα σε πίνακα:

cypher
MATCH (a:Personne)-[r:CONNAIT]->(b:Personne)
RETURN a.nom, type(r), r.depuis, b.nom
text
a.nom    type(r)    r.depuis  b.nom
"Alice"  "CONNAIT"  2024      "Bob"

Τι να προσέξεις: το type(r) δίνει τον τύπο του βέλους· το r.depuis την ιδιότητά του, ακριβώς όπως το p.nom για μια φυσαλίδα. Μια σχέση αντιμετωπίζεται όπως ένας κόμβος: τη βρίσκεις, την ονομάζεις, διαβάζεις και γράφεις μέσα της. Οι φυσαλίδες χωρίς προσωρινό όνομα, (:Personne {…}), είναι αυτές που δεν χρειάζεσαι μετά: μπορείς να παραλείψεις το γράμμα.

Βήμα 7 — Το βέλος έχει κατεύθυνση

cypher
MATCH (:Personne {nom: 'Bob'})-[:CONNAIT]->(x) RETURN x.nom

Τι ζητάει το ερώτημα: ποιον γνωρίζει ο Bob; Οι φυσαλίδες x στην άκρη ενός βέλους CONNAIT που ξεκινάει από τον Bob.

text
(no changes, no records)

Τι να προσέξεις: μηδέν γραμμές. Το μοναδικό βέλος πηγαίνει από την Alice προς τον Bob· κανένα δεν ξεκινάει από τον Bob. Τώρα χωρίς την αιχμή:

cypher
MATCH (:Personne {nom: 'Bob'})-[:CONNAIT]-(x) RETURN x.nom
text
x.nom
"Alice"

Το -[:CONNAIT]- χωρίς >: «ένα βέλος CONNAIT ανάμεσα στον Bob και το x, προς οποιαδήποτε κατεύθυνση». Η Alice εμφανίζεται. Κράτησε το: στη γραφή, η κατεύθυνση είναι υποχρεωτική· στην ανάγνωση, επιλέγεις αν θα τη λάβεις υπόψη ή όχι. Αυτό κάνει το «ποιος συνδέεται με ποιον» τόσο σύντομο να γραφτεί σε Cypher.

Βήμα 8 — Σύνδεση της φυσαλίδας σου με τον πραγματικό γράφο

cypher
MATCH (a:Personne {nom: 'Alice'}), (c:Cours {id: 'C0001'})
CREATE (a)-[:AIME]->(c)

Τι ζητάει το ερώτημα: βρες την Alice, βρες το μάθημα C0001 του συνόλου δεδομένων, δημιούργησε ένα βέλος AIME από τη μία προς την άλλη.

Απολογισμός: Created 1 relationship.

Η Alice είναι τώρα συνδεδεμένη με μια φυσαλίδα που υπήρχε πριν από σένα. Δες όλα όσα ξεκινούν από αυτήν:

cypher
MATCH (a:Personne {nom: 'Alice'})-[r]->(x)
RETURN a.nom, type(r), labels(x)[0] AS type_cible, coalesce(x.nom, x.titre) AS cible
text
a.nom    type(r)    type_cible  cible
"Alice"  "AIME"     "Cours"     "Docker expliqué simplement"
"Alice"  "CONNAIT"  "Personne"  "Bob"

Τι να προσέξεις: δύο γραμμές, δύο τύποι βέλους, δύο τύποι στόχου. Το labels(x)[0] δίνει την ετικέτα της φυσαλίδας στην άκρη· το coalesce(x.nom, x.titre) παίρνει το nom αν υπάρχει, αλλιώς το titre (ο Bob έχει nom, το μάθημα έχει titre). Αυτός είναι ο πίνακας-παραδοτέο σου: κράτησέ τον. Σε SQL, θα χρειαζόταν μια σύνδεση ανά πίνακα-στόχο και ένα UNION· εδώ, μία μόνο γραμμή MATCH.

Πέρασε σε προβολή Graph στο MATCH (a:Personne {nom: 'Alice'})-[r]->(x) RETURN a, r, x: η Alice στο κέντρο, ο Bob από τη μία, το μάθημα από την άλλη, σε δύο χρώματα (ένα ανά ετικέτα).

Βήμα 9 — Μέτρημα

cypher
MATCH (n) RETURN count(n) AS noeuds
text
noeuds
874

872 + οι 2 φυσαλίδες σου. Ανά ετικέτα:

cypher
MATCH (n) RETURN labels(n)[0] AS label, count(*) ORDER BY label
text
label         count(*)
"Competence"  22
"Cours"       504
"Etudiant"    300
"Personne"    2
"Professeur"  30
"Ville"       16

Τι να προσέξεις: μια έκτη γραμμή, Personne 2. Σε ένα τερματικό, το .\labo.ps1 etat ή το ./labo.sh etat εμφανίζει τώρα ✔ Neo4j répond — nœuds : 874. Το σενάριο και το Neo4j Browser μετρούν το ίδιο πράγμα με δύο διαδρομές: είναι η διασταυρούμενη επαλήθευση της καθοδηγούμενης πρακτικής, εφαρμοσμένη σε ό,τι δημιούργησες εσύ.

Βήμα 10 — Καθαρισμός, και συνάντηση με το σφάλμα που εξηγεί τα πάντα

Δοκίμασε πρώτα την αφελή διαγραφή:

cypher
MATCH (p:Personne) DELETE p
text
Neo.ClientError.Schema.ConstraintValidationFailed
Cannot delete node<874>, because it still has relationships. To delete this node, you must first delete its relationships.

Τι να προσέξεις: ένα κόκκινο πλαίσιο, τίποτα δεν διαγράφηκε. Το Neo4j αρνείται να σβήσει μια φυσαλίδα που έχει ακόμα βέλη: ένα βέλος χωρίς φυσαλίδα στην άκρη δεν θα είχε νόημα. Ο αριθμός node<874> είναι ο εσωτερικός αναγνωριστικός κωδικός της πρώτης φυσαλίδας που προσπάθησε να διαγράψει· σε σένα διαφέρει. Είναι το ισοδύναμο μιας παραβίασης ξένου κλειδιού σε SQL, με μια διαφορά: εδώ, η λύση χωράει σε μία λέξη.

cypher
MATCH (p:Personne) DETACH DELETE p

Τι ζητάει το ερώτημα: βρες τις φυσαλίδες Personne, απόσπασέ τες (διάγραψε τα βέλη τους), μετά διάγραψέ τες.

Απολογισμός: Deleted 2 nodes, deleted 2 relationships.

Δύο κόμβοι, δύο σχέσεις: CONNAIT και AIME. Το μάθημα C0001 δεν επηρεάστηκε, μόνο το βέλος που οδηγούσε σε αυτό εξαφανίστηκε. Επαλήθευσε:

cypher
MATCH (n) RETURN count(n) AS noeuds
text
noeuds
872

Το MATCH (n) RETURN labels(n)[0] AS label, count(*) ORDER BY label δίνει ξανά πέντε γραμμές, χωρίς Personne, και η etat λέει κόμβοι: 872.

Για να κατανοήσεις καλά
  • Το DETACH DELETE είναι η κανονική κίνηση για τη διαγραφή ενός κόμβου στο Neo4j· το DELETE μόνο του εξυπηρετεί μόνο για έναν κόμβο που ξέρεις ότι είναι απομονωμένος, ή για τη διαγραφή μιας σχέσης: MATCH ()-[r:AIME]->() DELETE r σβήνει το βέλος και κρατάει τις φυσαλίδες.
  • Η ενότητα 6 θα σε κάνει να γράψεις MERGE αντί για CREATE: «δημιούργησε αν δεν υπάρχει, αλλιώς επαναχρησιμοποίησε». Αυτό επιτρέπει στο σενάριο charger-graphe να επανεκτελείται χωρίς διπλότυπα. Με το CREATE, η επανεκτέλεση του βήματος 4 θα είχε φτιάξει έναν δεύτερο Bob.
  • Τίποτα από όσα έκανες δεν έμεινε. Ο γράφος επέστρεψε στην αρχική του κατάσταση, ακριβώς όπως μετά το DELETE pratique-mini στο ερευνητικό εργαστήριο 1. Απόκτησε τη συνήθεια: ό,τι δημιουργείς για να μάθεις, το διαγράφεις στο τέλος.

Τελικός έλεγχος

  • Δημιούργησες έναν κόμβο με μία μόνο ετικέτα και είδες ότι δεν έχει καμία ιδιότητα.
  • Του έδωσες nom, μετά age και ville, με SET, βρίσκοντάς τον πρώτα με MATCH.
  • Δημιούργησες τον Bob με τις τιμές του σε ένα ερώτημα, και είδες null εκεί όπου λείπει μια ιδιότητα.
  • Δημιούργησες το CONNAIT ανάμεσα σε δύο υπάρχουσες φυσαλίδες, έβαλες depuis πάνω του, και διάβασες type(r) και r.depuis σε πίνακα.
  • Ξέρεις να εξηγήσεις γιατί το (Bob)-[:CONNAIT]->(x) δεν δίνει τίποτα και το (Bob)-[:CONNAIT]-(x) δίνει την Alice.
  • Σύνδεσες την Alice με το μάθημα C0001 και κράτησες τον πίνακα δύο γραμμών του βήματος 8 ως παραδοτέο.
  • Είδες το σφάλμα Cannot delete node … because it still has relationships, μετά το DETACH DELETE έδωσε Deleted 2 nodes, deleted 2 relationships.
  • Το MATCH (n) RETURN count(n) και η etat λένε 872.

Αν κάτι μπλοκάρει

Εμφάνιση συχνών περιπτώσεων
  • Invalid input, expected … σε κόκκινο → συντακτικό λάθος. Οι τρεις πιο συχνές αιτίες: μια παρένθεση ( κλεισμένη με μια αγκύλη ], μια αιχμή βέλους ξεχασμένη στη γραφή (-[:CONNAIT]- σε ένα CREATE απορρίπτεται: Only directed relationships are supported in CREATE), ένα εισαγωγικό που λείπει γύρω από ένα κείμενο.
  • Variable `r` not defineda, p…) → χρησιμοποιείς ένα γράμμα στο SET ή στο RETURN που κανένα MATCH ή CREATE του ίδιου ερωτήματος δεν εισήγαγε. Παράδειγμα: SET r.depuis = 2024 ενώ το βέλος γράφτηκε -[:CONNAIT]-> χωρίς το r. Πρόσθεσε το γράμμα εκεί που εμφανίζεται το αντικείμενο: -[r:CONNAIT]->.
  • Το βήμα 5 δημιούργησε επιπλέον άδειες φυσαλίδες (Created 2 nodes, created 1 relationship, και το Results overview δείχνει * (4)) → πληκτρολόγησες CREATE (a)-[:CONNAIT]->(b) χωρίς το MATCH ακριβώς πριν, ή με ερωτηματικό ανάμεσα στις δύο γραμμές. Τα a και b ήταν άγνωστα: το Neo4j δεν διαμαρτύρεται, τα επινοεί, χωρίς ετικέτα ή ιδιότητα. Καθάρισε: MATCH (n) WHERE size(labels(n)) = 0 DETACH DELETE n, μετά ξανακάνε το βήμα 5 σε ένα μόνο ερώτημα.
  • Δύο Alice ή δύο Bob (το MATCH (p:Personne) RETURN count(p) δίνει πάνω από 2) → ξανάτρεξες ένα CREATE. MATCH (p:Personne) DETACH DELETE p και ξεκίνα ξανά από το βήμα 1· η ενότητα 6 θα σου μάθει το MERGE, που το αποφεύγει αυτό.
  • Cannot delete node … because it still has relationships → είναι το βήμα 10, αναμενόμενο. DETACH DELETE.
  • Η φυσαλίδα εμφανίζει έναν αριθμό ή <id> αντί για Alice → το Browser δεν ξέρει ακόμα ποια ιδιότητα να δείξει. Κάνε κλικ στο σήμα Personne κάτω από τον γράφο και επίλεξε nom ως λεζάντα· ή διάβασε σε προβολή Table.
  • Η etat λέει ακόμα κόμβοι: 872 μετά τις δημιουργίες σου → είσαι συνδεδεμένος σε άλλη βάση ή άλλο Neo4j (ένα neo4j εγκατεστημένο τοπικά στη θύρα 7687;). Στο Browser, η μπάρα πάνω πρέπει να λέει neo4j://localhost:7687 και Database: neo4j· αλλιώς, κλείσε το άλλο Neo4j ή άλλαξε τη θύρα του.
  • Neo.ClientError.Security.Unauthorized → ο κωδικός πρόσβασης απορρίφθηκε. Είναι aiopsatlas2026· αν τον άλλαξες και τον έχασες, ./labo.sh reinitialiser μετά demarrer και charger-graphe (τα δεδομένα του kit φορτώνονται ξανά ίδια).