我有一个包含两种节点的定向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"})
在此示例中,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,因此我不必担心循环。
这可以在Cypher中完成吗?或者有人可以建议通过Java接口的有效方法(例如遍历策略)?感谢。
答案 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;
说明:
WHERE
块只是证明路径的源和目标都必须在“Set1”中。WHERE
块的最后一部分确实有趣。长度为1的路径是正常的(零中间“Set2”节点)。但是如果有中间节点,我们要做的就是检查所有“内部”节点是否都是“Set2”。带filter
表达式的tail
位只会删除路径中的第一个和最后一个节点(我们已经知道node1
和node2
)。然后all
表达式坚持认为如果中间有任何东西,它必须是Set2
节点(标记为“T”或“U”)。