Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Graph Neo4j:及时匹配多个关系_Graph_Neo4j_Cypher - Fatal编程技术网

Graph Neo4j:及时匹配多个关系

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)

考虑使用两种类型的边相互连接的以下节点:直接和相交。查询需要发现满足以下所有规则的2个节点之间的所有可能路径:

  • 0..N直边
  • 0..1相交边
  • 相交边可以位于直接边之间
这些路径在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避免了,不是吗?)

看起来很有希望但未能在几秒钟内完成的查询:


匹配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..]
,这意味着它不是可选的。请用您的输入进行更正。我尝试过,但从未完成(我让它运行了至少半个小时)。请用一些见解检查更新后的问题可能因为循环引用而如此糟糕?