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



我有一个包含 2 种节点的有向 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"})

在这个例子中,ABCDE 在集合 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,所以我不必担心循环。

这可以在密码中完成吗? 或者有人可以通过Java接口提出一种有效的方法(例如遍历策略(吗? 谢谢。

是的,可以完成 - 这是一个复杂的查询,因此您可能需要稍微使用它,但这里有一些东西可以开始。 也许其他人可以来改进这一点,但我认为这应该完成大部分基本逻辑。

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"。 带有 tail 表达式的 filter 位只是从路径中切掉第一个和最后一个节点(我们已经知道这是node1node2(。 然后all表达式坚持认为,如果中间有什么东西,它一定是一个Set2节点(标记为"T"或"U"(。
  3. 最后,通过这两个匹配的节点,我们创建了一个漂亮的新关系,直接连接它们。

最新更新