如何在子图上发出请求?

时间:2018-12-06 18:13:49

标签: neo4j cypher subgraph

我尝试执行以下请求:

MATCH path = (f1:Frag)-[r1:I]->(f2:Frag)-[r2:I]->(f3:Frag)-[r3:I]->
 (f4:Frag)-[r4:I]->(f5:Frag)-[r5:I]->(f6:Frag)
 WHERE (r1.at2 <> r2.at1 AND r2.at2 <> r3.at1 AND r3.at2 <> r4.at1
  AND r4.at2 <> r5.at1) AND (not((f1)-[:E]-(f3)) AND not((f1)-[:E]-(f4))
  AND not((f1)-[:E]-(f5)) AND not((f1)-[:E]-(f6)) AND not((f2)-[:E]-(f4))
  AND not((f2)-[:E]-(f5)) AND not((f2)-[:E]-(f6)) AND not((f3)-[:E]-(f5))
  AND not((f3)-[:E]-(f6)) AND not((f4)-[:E]-(f6)))
RETURN path LIMIT 10 

但是当我想将请求限制为某些关系时,例如:

MATCH path = (f1:Frag)-[r1:I]->(f2:Frag)-[r2:I]->(f3:Frag)-[r3:I]->
 (f4:Frag)-[r4:I]->(f5:Frag)-[r5:I]->(f6:Frag)
 WHERE (r1.at2 <> r2.at1 AND r2.at2 <> r3.at1 AND r3.at2 <> r4.at1
  AND r4.at2 <> r5.at1) AND (not((f1)-[:E]-(f3)) AND not((f1)-[:E]-(f4))
  AND not((f1)-[:E]-(f5)) AND not((f1)-[:E]-(f6)) AND not((f2)-[:E]-(f4))
  AND not((f2)-[:E]-(f5)) AND not((f2)-[:E]-(f6)) AND not((f3)-[:E]-(f5))
  AND not((f3)-[:E]-(f6)) AND not((f4)-[:E]-(f6)))
  AND ALL(r in relationships(path) WHERE r.niv <20)
RETURN path LIMIT 10

查找解决方案要比在所有关系上花费更多的时间,因为它使用了所有关系。

是否可以将请求限制为子图?

1 个答案:

答案 0 :(得分:1)

以下简化的查询形式在逻辑上应与您的查询等效(如果来自I节点的Frag关系始终以Frag节点结尾),并返回所需路径的有序关系和节点。 (实际上,您可以只返回rs,因为关系包含对其起点和终点的引用)。此查询的profile也比您的查询简单得多,因此此查询可能更快。

MATCH p = (:Frag)-[:I*5]->(:Frag)
WITH RELATIONSHIPS(p) AS rs, NODES(p) AS ns
WHERE
  ALL(i IN RANGE(0, SIZE(rs)-2) WHERE rs[i].at2 <> rs[i+1].at1) AND
  ALL(j IN ns[0..-2] WHERE ALL(k IN ns[2..] WHERE NOT (j)-[:E]-(k))) AND
  ALL(r in rs WHERE r.niv < 20)
RETURN *
LIMIT 10