neo4j - 如何获取neo4j中特定节点的所有子节点

标签 neo4j cypher graph-databases

在我的neo4j中有这种关系:

Parent -> Childs
F -> D,E
D -> A,B,C

用例:我尝试使用此查询获取特定节点的所有子节点

MATCH (p:Person{name:"F"})<-[:REPORTS_TO*]-(c) 
RETURN {parent : p.name, child : {name :collect( c.name)}}

这返回给我:

{"parent":"F","child":{"name":["D","A","B","C","E"]}}

A、B、C 不是 F 的直接子代,因为它们是 D 的子代

所需回复为

[
"F" : [ Childs i.e "E", "D" ]
"E" : []
"D" : [ "A", "B", "C" ]
 and so on ....
]

实现此目的的一种方法是递归地触发以下查询:

MATCH (p:Person{name:"F"})<-[:REPORTS_TO]-(c) 
RETURN {parent : p.name, child : {name :collect( c.name)}}

返回结果

{"parent":"F","child":{"name":["E","D"]}}

然后搜索 E 和 D 的所有子级,然后搜索子级的子级,依此类推。

我的问题是我可以通过单个查询还是以更好的方式实现此目的?

编辑1:添加数据集

CREATE (f:Person {name: "F"})
CREATE (e:Person {name: "E"})
CREATE (d:Person {name: "D"})
CREATE (c:Person {name: "C"})
CREATE (b:Person {name: "B"})
CREATE (a:Person {name: "A"})
CREATE (x:Person {name: "X"})
CREATE (a)-[:REPORTS_TO]->(x)
CREATE (d)-[:REPORTS_TO]->(a)
CREATE (d)-[:REPORTS_TO]->(b)
CREATE (d)-[:REPORTS_TO]->(c)
CREATE (f)-[:REPORTS_TO]->(d)
CREATE (f)-[:REPORTS_TO]->(e)

最佳答案

您可以使用OPTIONAL MATCH实现您的目标。

您的数据集如下所示:

Data set

尝试一下:

MATCH (p:Person)
OPTIONAL MATCH (p)<-[:REPORTS_TO]-(c) 
RETURN {parent : p.name, child : {name :collect( c.name)}}

查询结果:

+-----------------------------------------------------+
| {parent : p.name, child : {name :collect( c.name)}} |
+-----------------------------------------------------+
| {parent=D, child={name=[C, B, A]}}                  |
| {parent=A, child={name=[]}}                         |
| {parent=C, child={name=[]}}                         |
| {parent=F, child={name=[E, D]}}                     |
| {parent=E, child={name=[]}}                         |
| {parent=B, child={name=[]}}                         |
+-----------------------------------------------------+

如果您只需要特定的 parent 和您各自的 child ,您可以这样做:

MATCH (p:Person)
WHERE p.name = "D"
OPTIONAL MATCH (p)<-[:REPORTS_TO]-(c) 
WITH COLLECT (c) + p AS all
UNWIND all as p
MATCH (p)
OPTIONAL MATCH (p)<-[:REPORTS_TO]-(c) 
RETURN {parent : p.name, child : {name :collect( c.name)}}

结果:

+-----------------------------------------------------+
| {parent : p.name, child : {name :collect( c.name)}} |
+-----------------------------------------------------+
| {parent=D, child={name=[C, B, A]}}                  |
| {parent=A, child={name=[]}}                         |
| {parent=C, child={name=[]}}                         |
| {parent=B, child={name=[]}}                         |
+-----------------------------------------------------+

编辑:

摘自@Prakash Pandey 的评论:

how can we do something like childs, childs of childs and so on where p.name = "Tom"

根据问题中添加的数据集,您可以执行以下操作:

MATCH (p:Person)<-[:REPORTS_TO*]-(c:Person)
WHERE p.name = "X"
WITH COLLECT (c) + p AS all UNWIND all as p
MATCH (p)<-[:REPORTS_TO]-(c)
RETURN {parent : p.name, child : {name :collect( c.name)}}

结果:

+-----------------------------------------------------+
| {parent : p.name, child : {name :collect( c.name)}} |
+-----------------------------------------------------+
| {parent=D, child={name=[F]}}                        |
| {parent=A, child={name=[D]}}                        |
| {parent=X, child={name=[A]}}                        |
+-----------------------------------------------------+

关于neo4j - 如何获取neo4j中特定节点的所有子节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44025445/

相关文章:

Neo4j,密码 : Conditional Create

shell - neo4j csv 导入生命迹象

Neo4j 节点属性类型

java - Java 中的 Gremlin group By

visualization - ArangoDB 和 Gephi : Import data from ArangoDB into Gephi

java - SDN 4 + OGM 1.1.1 @Index(unique = true) 不起作用

graph - 使用 Neo4j Cypher 获取没有第一个或最后一个节点的最长路径

neo4j - 与属性(和标签?)的可选匹配

php - Neo4j 中的密码限制包括重复行

python - py2neo graph.merge() 的行为与 Cypher MERGE 不同?