Graph Neo4j:及时匹配多个关系
考虑使用两种类型的边相互连接的以下节点:直接和相交。查询需要发现满足以下所有规则的2个节点之间的所有可能路径:Graph Neo4j:及时匹配多个关系,graph,neo4j,cypher,Graph,Neo4j,Cypher,考虑使用两种类型的边相互连接的以下节点:直接和相交。查询需要发现满足以下所有规则的2个节点之间的所有可能路径: 0..N直边 0..1相交边 相交边可以位于直接边之间 这些路径在nodeA和nodeZ之间被认为是有效的: (nodeA)-[:direct]>(nodeB)-[:direct]>(nodeC)->[:direct]>(nodeZ) (nodeA)-[:intersect]>(nodeB)-[:direct]>(nodeC)->[:direct]>(nodeZ) (nodeA)
- 0..N直边
- 0..1相交边
- 相交边可以位于直接边之间
(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)
MATCH(from)-[:direct*0..N |:intersect*0..1]->(to)
但neo4j不支持边类型的多个约束:(
更新日期23.04.16
有6609个节点(总共550k个),5184个直接类型的边(总共440k个)和34119个相交类型的边(总共37289个)。预计会有一些循环引用(neo4j避免了,不是吗?)
看起来很有希望但未能在几秒钟内完成的查询:
匹配p=(从{from:1})-[:direct | intersect*0..]>(到{to:99})
哪里
123 并减少(关系(p)中的s=0,x)|当“相交”时的大小写类型(x),然后是s+1,否则为s END)这将满足您的要求:
// 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
我犯了一个错误,认为浏览器上的图表反映了以“p”返回的数据-事实并非如此,您必须查看报告的“行”部分才能获得所有详细信息
此查询还将返回符合要求的单个节点。以下是符合所述要求的查询:
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;
MATCH p=(from)-[:direct | intersect*0..]>(to)
其中REDUCE(s=0,x在关系(p)中)|
案例当类型(x)=“intersect”然后是s+1或s END)时,您的查询不符合规定的要求。它只返回以至少一个direct
开头的路径,然后是一个intersect
,最后是至少一个direct
。您可以修改它以使其正常工作(但它可能没有我的答案那么好):匹配p=((from)-[:direct*0..]>(middle)-[:intersect*0..1]>(middle2)-[:direct*0..]>(to))返回不同的p;
唯一的要求是在图中存在一条相交边,这是存在的。如果相交边也是可选的,那么[:intersect]可以替换为[:intersect*]。intersect
不是必需的[0..1],也不是直接的[0..N]。并且不要求路径必须以直接的开始和结束。顺便说一句,[:intersect*]
与[:intersect*1..]
,这意味着它不是可选的。请用您的输入进行更正。我尝试过,但从未完成(我让它运行了至少半个小时)。请用一些见解检查更新后的问题可能因为循环引用而如此糟糕?