【问题标题】:How to get all childs of a particular node in neo4j如何在neo4j中获取特定节点的所有子节点
【发布时间】:2017-05-17 12:52:54
【问题描述】:

在我的 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 and D 的所有孩子,然后搜索孩子的孩子等等..

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

Edit1:添加数据集

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)

【问题讨论】:

    标签: neo4j cypher graph-databases


    【解决方案1】:

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

    您的数据集如下所示:

    试试看:

    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=[]}}                         |
    +-----------------------------------------------------+
    

    如果您只需要特定的父母和您各自的孩子,您可以这样做:

    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 的评论:

    我们怎样才能在哪里做像孩子、孩子的孩子等等这样的事情 p.name = "汤姆"

    根据题中添加的数据集,可以这样做:

    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]}}                        |
    +-----------------------------------------------------+
    

    【讨论】:

    • 这个搜索整个图,我们怎么能做像childs,childs of childs之类的事情 where p.name = "Tom"
    • Bruno 能否请您验证一下,我尝试了您的查询 MATCH (p:Person) WHERE p.name = "X" OPTIONAL MATCH (p)&lt;-[:REPORTS_TO]-(c) WITH COLLECT (c) + p AS all UNWIND all as p MATCH (p) OPTIONAL MATCH (p)&lt;-[:REPORTS_TO]-(c) RETURN {parent : p.name, child : {name :collect( c.name)}},它返回的节点最多只有 2 个级别 "{parent : p.name, child : {name :collect( c.name)}}" {"parent":"A","child":{"name":["D"]}} {"parent":"X","child":{"name":["A"]}} 我已经添加了我的查询,我正在使用它来插入数据,这样您就不会拥有来写。请看一下
    • 注意我已经在我的问题的编辑部分添加了查询,我使用它来插入数据,当使用如上所述的你的查询时,它只返回我的孩子高达 2 级
    • 理想情况下应该返回X-&gt;A, A-&gt;D, D-&gt;F
    • 但它只返回X-&gt;A, A-&gt;D and not D-&gt;F
    【解决方案2】:

    我创建了你描述的图表。

    以下查询返回您需要的大部分内容:

    MATCH (a:Parent)<-[r:isParent*0..]-(b:Parent)
    return {parent:a.name,child : {name :collect( b.name)}}
    

    结果:

    {"父":"D","子":{"name":["D","A","B","C"]}}

    {"父":"A","子":{"name":["A"]}}

    {"父":"C","子":{"name":["C"]}}

    {"父":"F","子":{"name":["F","D","E","A","B","C"]}}

    {"父":"E","子":{"name":["E"]}}

    {"父":"B","子":{"name":["B"]}}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多