En interrogeant une base de données de graphes avec Cypher, j'essaie de parcourir une distance indéfinie dans un arbre à partir d'un nœud de départ et de renvoyer chaque nœud avec des informations sur les relations de ce nœud.
Par exemple, prenez un arbre généalogique:
Je voudrais commencer à "James" (noeud id 4), et obtenir une réponse avec des lignes pour chaque noeud avec les données de bord définissant les relations de ce noeud.
Si je fais quelque chose comme:
MATCH (p:Person)<-[r:Related]-(p2:Person) WHERE id(p)=4 RETURN id(p), p, collect(r.relationship), collect(id(p2))
Je reçois
Pour me débarrasser des données dupliquées, je peux collecter certains des résultats tels que:
MATCH (p:Person)<-[r:Related]-(p2:Person) WHERE id(p)=4 RETURN p, r, p2
Donne moi
Mais je n'ai encore que le nœud initial. Comment puis-je développer cela pour inclure des lignes dans ce format (ou quelque chose de similaire) pour chaque nœud tout en haut de l'arborescence, y compris les nœuds feuilles?
3 Réponses :
Ce que vous voulez, c'est faire correspondre les relations de longueur variable
MATCH (p:Person)<-[r:Related*1..]-(p2:Person) WHERE id(p)=4 AND id(p) <> id(p2) RETURN id(p), p, collect(r.relationship), collect(id(p2))
Merci pour la réponse. Cela me donne une erreur: Type mismatch: expected Any, Map, Node, Relationship, Point, Duration, Date, Time, LocalTime, LocalDateTime or DateTime but was List<Relationship> (line 3, column 26 (offset: 105)) "RETURN id(p), p, collect(r.relationship), collect(id(p2))"
. Mais même si ce n'était pas le cas, cela ne me montrerait-il pas simplement que mon point de départ est lié à tous les autres? Ce n'est pas exactement ce que je recherche. Je recherche chacun de ces nœuds, mais aussi des informations sur les voisins directs de chacun.
Il existe un certain nombre de façons d'imprimer des arbres, dont la plupart reposent sur des parcours de longueur variable comme @Vivick décrit. Si vous souhaitez imprimer chaque relation et nœud intermédiaire / feuille sur sa propre ligne, vous pouvez faire quelque chose comme:
MATCH (p:Person)<-[r:Related*]-(p2:Person) WHERE id(p)=4 WITH collect(r) AS rels, collect(p2) AS nodes UNWIND rels AS rel UNWIND nodes AS node RETURN rel, node
Vous pouvez également utiliser un algorithme de parcours pour ce faire. Dans RedisGraph, cette tâche pourrait être exécutée succinctement avec algo.BFS
; la plupart des bases de données de graphes ont des implémentations similaires.
J'ai fini par le faire en me connectant tous à ma cible, puis en collectant des informations sur la relation avec une optional match
:
match (p:Person)<-[*0..]-(p2) where id(p)=0 optional match (p2)<-[r]-(p3) return id(p2), p2.name, collect(r.relationship), collect(id(p3))
Cette requête va (je pense ... toujours comprendre cela):
Cela me donne un bon résultat avec une seule ligne par nœud, avec toutes les informations dont j'ai besoin sur ce nœud et les relations de ces nœuds avec d'autres nœuds.