选择单个有向无环图

时间:2016-03-16 23:30:28

标签: neo4j cypher

我是neo4j的新手,我正试图从图中提取单个有向非循环子图,以便能够迭代结果图(或节点和路径的集合)和跟踪每个节点所在的层(layers基于来自 根节点)。这可能在密码中吗?我正在使用REST api。

我所拥有的示例数据结构类似于以下子图,其中AH将是“根”节点:

A -+ B -+ D
     |    
     +   
H -+ C -+ E
     |
     +
     F


S*

BC各自为第1层,DEF为第2层。A和{{ 1}}与H:SUBGRAPH_ENTER的关系,我想要的子图中的所有节点都有S*:MEMBER_OF_SUBGRAPH的关系

以下查询将返回我想要的子图(piecemeal),但是,我不确定如何在路径中对节点进行排序。

S*

有人可以提供建议吗?

1 个答案:

答案 0 :(得分:2)

[EDITED]

如果您使用以下两个查询创建示例非循环图:

CREATE (s:Subgraph),
  (a:Foo {id:'A'}), (b:Foo {id:'B'}), (c:Foo {id:'C'}), (d:Foo {id:'D'}), (e:Foo {id:'E'}), (f:Foo {id:'F'}), (h:Foo {id:'H'}), 
  (a)-[:ARROW_TO]->(b)-[:ARROW_TO]->(d),
  (h)-[:ARROW_TO]->(c)-[:ARROW_TO]->(e),
  (b)-[:ARROW_TO]->(c)-[:ARROW_TO]->(f),
  (a)<-[:SUBGRAPH_ENTER]-(s),
  (h)<-[:SUBGRAPH_ENTER]-(s);

MATCH (f:Foo), (s:Subgraph)
CREATE (f)-[:MEMBER_OF_SUBGRAPH]->(s);

然后此查询将返回子图节点,按距离最近的根的距离排序:

MATCH p=(s)-[:SUBGRAPH_ENTER]->(root)-[:ARROW_TO*]->(leaf)
WHERE (NOT (leaf)-[:ARROW_TO]->()) AND ALL(n IN NODES(p)[1..] WHERE (n)-[:MEMBER_OF_SUBGRAPH]->(s))
WITH s, NODES(p)[2..] AS nodes
WITH s, REDUCE(s = [], i IN RANGE(0, SIZE(nodes)-1) | s + {node: nodes[i], dist: i+1}) AS data
UNWIND data AS datum
RETURN s, datum.node AS node, MIN(datum.dist) AS distance
ORDER BY distance;

WHERE子句过滤掉部分路径或其他子图中的节点。 第一个WITH子句收集从root节点之后开始的每个路径中的节点。 第二个WITH子句为第一个集合中的每个节点生成一组节点/距离对。 UNWIND将后一个集合转换为数据行,以便由MIN聚合函数进行处理。

结果如下:

+------------------------------------------+
| s          | node             | distance |
+------------------------------------------+
| Node[38]{} | Node[41]{id:"C"} | 1        |
| Node[38]{} | Node[40]{id:"B"} | 1        |
| Node[38]{} | Node[44]{id:"F"} | 2        |
| Node[38]{} | Node[43]{id:"E"} | 2        |
| Node[38]{} | Node[42]{id:"D"} | 2        |
+------------------------------------------+

包括根节点

如果要在输出中包含根节点,此查询将执行此操作:

MATCH p=(s)-[:SUBGRAPH_ENTER]->(root)-[:ARROW_TO*]->(leaf)
WHERE (NOT (leaf)-[:ARROW_TO]->()) AND ALL (n IN NODES(p)[1..] WHERE (n)-[:MEMBER_OF_SUBGRAPH]->(s))
WITH s, NODES(p)[1..] AS nodes
WITH s, REDUCE(s =[], i IN RANGE(0, SIZE(nodes)-1)| s + { node: nodes[i], dist: i }) AS data
UNWIND data AS datum
RETURN s, datum.node AS node, MIN(datum.dist) AS distance
ORDER BY distance;

结果如下:

+-----------------------------------------+
| s         | node             | distance |
+-----------------------------------------+
| Node[6]{} | Node[7]{id:"A"}  | 0        |
| Node[6]{} | Node[13]{id:"H"} | 0        |
| Node[6]{} | Node[8]{id:"B"}  | 1        |
| Node[6]{} | Node[9]{id:"C"}  | 1        |
| Node[6]{} | Node[10]{id:"D"} | 2        |
| Node[6]{} | Node[12]{id:"F"} | 2        |
| Node[6]{} | Node[11]{id:"E"} | 2        |
+-----------------------------------------+