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

Neo4j 从现有节点的子集创建图形,neo4j,cypher,traversal,Neo4j,Cypher,Traversal,我有一个有向Neo4j图,它包含两种节点:集合1中有标签的节点和集合2中有标签的节点。我希望在集合1中的节点之间创建新边(新类型),只要存在从集合1节点到另一集合1节点的定向路径,该路径仅通过集合2节点(可能为0个这样的集合2节点) 下面是一个示例数据集: CREATE (a:A {id:"a"})-[:CONN]->(t1:T {id:"t1"}), (t1)-[:CONN]->(b1:B {id:"b1"}), (b1)-[:CONN]->(t2:U {id:"

我有一个有向Neo4j图,它包含两种节点:集合1中有标签的节点和集合2中有标签的节点。我希望在集合1中的节点之间创建新边(新类型),只要存在从集合1节点到另一集合1节点的定向路径,该路径仅通过集合2节点(可能为0个这样的集合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"})
在本例中,
A
B
C
D
,&
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,所以我不必担心循环


这能用密码完成吗?或者有人可以建议一种通过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;
MATCH p=(node1)-[*]-(node2)
其中标签(节点1)中的('A')或
标签中的“B”(节点1)或
标签中的“C”(节点1)或
标签中的“D”(节点1)或
标签中的“E”(节点1))
及
(“A”在标签中(节点2)或
标签中的“B”(节点2)或
标签中的“C”(节点2)或
标签中的“D”(节点2)或
标签中的“E”(节点2))
及
(长度(p)=1或
全部(中间节点)
过滤器(n在尾部(节点(p)),其中n在最后(节点(p)))
哪里
(“T”在标签中(中间节点)或
标签中的“U”(intermedNode)))
使用node1,node2
创建节点1-[:MyNewNiftyEdge]->node2;
说明:

  • 我们在寻找道路;前两个大的
    ,其中
    块只是证明路径的源和目标都必须在“Set1”中
  • 块的最后一部分,其中
    块执行所有有趣的操作。长度为1的路径正常(零中间“Set2”节点)。但如果有中间节点,我们要做的是检查所有“内部”节点是否都是“Set2”。带有
    tail
    表达式的
    filter
    位只从路径中删除第一个和最后一个节点(我们已经知道这是
    node1
    node2
    )。然后,<代码>所有< /COD>表达式坚持,如果中间有任何东西,它必须是<代码> SET2节点(标记为“T”或“u”)。< /LI>
  • 最后,通过这两个匹配的节点,我们创建了一个漂亮的新关系,将它们直接连接起来

  • 太棒了,谢谢。我也开始编写一个带有Java接口的解决方案,如果这个解决方案可行的话,我也可以在这里发布。