从现有节点的子集创建图表

时间:2015-06-29 19:56:51

标签: neo4j cypher traversal

我有一个包含两种节点的定向Neo4j图:第1组中带有标签的节点和第2组中带有标签的节点。我想在Set中的节点之间创建新的边(新类型) 1,每当存在从Set 1节点到另一个Set 1节点的有向路径时,该节点仅通过Set 2节点(可能是0个这样的Set 2节点)。

以下是一个示例数据集:

CREATE (a:A {id:"a"})-[:CONN]->(t1:T {id:"t1"}),
   (t1)-[:CONN]->(b1:B {id:"b1"}),
   (b1)-[:CONN]->(t2:U {id:"t1"}),
   (t2)-[:CONN]->(c1:C {id:"c1"}),
   (c1)-[:CONN]->(t3:T {id:"t3"}),
   (t3)-[:CONN]->(d1:D {id:"d1"}),
   (t3)-[:CONN]->(d2:D {id:"d2"}),
   (d1)-[:CONN]->(t4:T {id:"t4"}),
   (d2)-[:CONN]->(t4),
   (t4)-[:CONN]->(e1:E {id:"e1"}),
   (t4)-[:CONN]->(e2:E {id:"e2"})

在此示例中,ABCD和& E位于第1集,T& U位于第2集中,因此我想绘制新的:AGG边缘,如下所示:

MATCH (a:A {id:"a"}), (b1:B {id:"b1"}), (c1:C {id:"c1"}), (d1:D {id:"d1"}),
      (d2:D {id:"d2"}), (e1:E {id:"e1"}), (e2:E {id:"e2"})
CREATE (a)-[:AGG]->(b1),
   (b1)-[:AGG]->(c1),
   (c1)-[:AGG]->(d1),
   (c1)-[:AGG]->(d2),
   (d1)-[:AGG]->(e1),
   (d1)-[:AGG]->(e2),
   (d2)-[:AGG]->(e1),
   (d2)-[:AGG]->(e2)

关于CONN边缘,我知道图表是DAG,因此我不必担心循环。

这可以在Cypher中完成吗?或者有人可以建议通过Java接口的有效方法(例如遍历策略)?感谢。

1 个答案:

答案 0 :(得分:3)

是的,它可以完成 - 这是一个复杂的查询,所以你可能需要稍微玩一下,但这里有一些东西可以开始。也许其他人可以在这方面进行改进,但我认为这应该完成大部分基本逻辑。

MATCH p=(node1)-[*]-(node2)
WHERE ('A' in labels(node1) OR
       'B' in labels(node1) OR
       'C' in labels(node1) OR
       'D' in labels(node1) OR
       'E' in labels(node1)) 
      AND
      ('A' in labels(node2) OR
       'B' in labels(node2) OR
       'C' in labels(node2) OR
       'D' in labels(node2) OR
       'E' in labels(node2)) 
      AND
      (length(p) = 1 OR 
       all(intermedNode in 
           filter(n IN tail(nodes(p)) WHERE n <> last(nodes(p)))
           WHERE
           ('T' in labels(intermedNode) OR
            'U' in labels(intermedNode))))
WITH node1, node2
CREATE node1-[:MyNewNiftyEdge]->node2;

说明:

  1. 我们正在寻找路径;前两个大的WHERE块只是证明路径的源和目标都必须在“Set1”中。
  2. WHERE块的最后一部分确实有趣。长度为1的路径是正常的(零中间“Set2”节点)。但是如果有中间节点,我们要做的就是检查所有“内部”节点是否都是“Set2”。带filter表达式的tail位只会删除路径中的第一个和最后一个节点(我们已经知道node1node2)。然后all表达式坚持认为如果中间有任何东西,它必须是Set2节点(标记为“T”或“U”)。
  3. 最后,通过这两个匹配的节点,我们创建了一个很好的新关系,直接连接它们。