考虑使用两种类型的边相互连接的节点:直接和相交。查询需要发现满足以下所有规则的2个节点之间的所有可能路径:
这些路径在nodeA和nodeZ之间被认为是有效的:
(nodeA)-[:direct]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)
(nodeA)-[:intersect]->(nodeB)-[:direct]->(nodeC)->[:direct]->(nodeZ)
(nodeA)-[:direct]->(nodeB)-[:intersect]->(nodeC)->[:direct]->(nodeZ)
(nodeA)-[:direct]->(nodeB)->[:direct]->(nodeC)-[:intersect]->(nodeZ)
基本上相交边可以发生在路径中的任何地方,但只能发生一次。 我在不存在的neo4j版本中的理想密码查询是这样的:
MATCH (from)-[:direct*0..N|:intersect*0..1]->(to)
但是neo4j并不支持边类型的多个约束:(。
更新23.04.16
有6609个节点(总共550k),5184个直接类型的边缘(总共440k)和34119个类型相交(总共37289个)。预期会有一些循环引用(neo4j避免了,不是吗?)
看起来很有希望但却未能以秒的方式完成的查询:
MATCH p = (from {from: 1})-[:direct|intersect*0..]->(to {to: 99})
WHERE
123 < from.departureTS < 123 + 86400 //next day
AND REDUCE(s = 0, x IN RELATIONSHIPS(p) | CASE TYPE(x) WHEN 'intersect' THEN s + 1 ELSE s END) <= 1
return p;
答案 0 :(得分:2)
这是符合规定要求的查询:
MATCH p = (from)-[:direct|intersect*0..]->(to)
WHERE REDUCE(s = 0, x IN RELATIONSHIPS(p) |
CASE WHEN TYPE(x) = 'intersect' THEN s + 1 ELSE s END) <= 1
return p;
它返回所有具有0个或更多direct
个关系以及0或1个intersect
关系的路径。
答案 1 :(得分:1)
这将做你想要的:
// Cybersam's correction:
MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)) return DISTINCT p;
return p
这是我使用的测试场景:
create (a:nodeA {name: "A"})
create (b:nodeB {name: "B"})
create (c:nodeC {name: "C"})
create (z:nodeZ {name: "Z"})
merge (a)-[:direct {name: "D11"}]->(b)-[:direct {name: "D21"}]->(c)-[:direct {name: "D31"}]->(z)
merge (a)-[:intersect {name: "I12"}]->(b)-[:direct {name: "D22"}]->(c)-[:direct {name: "D32"}]->(z)
merge (a)-[:direct {name: "D13"}]->(b)-[:intersect {name: "I23"}]->(c)-[:direct {name: "D33"}]->(z)
merge (a)-[:direct {name: "D14"}]->(b)-[:direct {name: "D24"}]->(c)-[:intersect {name: "I34"}]->(z)
merge (a)-[:intersect {name: "I15"}]->(z)
// Cybersam's correction:
MATCH p = ((from)-[:direct*0..]->(middle)-[:intersect*0..1]->(middle2)-[:direct*0..]->(to)) return DISTINCT p;
return p
我错误地认为浏览器上的图形反映了&#34; p&#34;中返回的数据。 - 它没有,你必须看看&#34;行&#34;获取所有细节的报告的一部分。
此查询还将返回符合要求的单个节点。