我使用Neo4j建模了一个水网。管道是标签为“管道”的节点。位于管道之间的阀门和其他组件是具有标签“节点”的节点。我已经将第二个标签(:dm)添加到:将运营网络区域分开的节点。最后,我将中断节点连接到特定管道,标记供水受影响的地方,比如爆裂。域名如下:
(:interruption)-[:ON]->(:pipe)
(:pipe)-[:LINKED]->(:pipe)
(:pipe)-[:LINKED]->(:node)
(:node)-[:LINKED]->(:pipe)
我正在尝试从中断开始返回网络,并在所有方向上传播但不通过dm节点。这基本上模仿了我们用GIS做的那种痕迹。以下面的查询为例,有时我会得到所有可能的方向,在其他情况下,如果我改变了链接数量,我只会得到一个/一些方向。
如何编写查询以始终如一地返回所有方向?
样本1:分支在两个方向上延伸,通过一个dm节点
// Linked up to 100
MATCH (i:interruption {ID:40})-[r1:ON]->(p:pipe)
MATCH (p)-[r2:LINKED]-(p2)
MATCH (p2)-[r3:LINKED*0..100]-(:dm)
return r1, r2, r3 limit 200
样本2: 分支仅在一个方向上延伸
// Linked up to 200
MATCH (i:interruption {ID:40})-[r1:ON]->(p:pipe)
MATCH (p)-[r2:LINKED]-(p2)
MATCH (p2)-[r3:LINKED*0..200]-(:dm)
return r1, r2, r3 limit 200
答案 0 :(得分:1)
我认为问题在于您的上一个MATCH
子句要求所有找到的路径在dm
节点上结束。
在第一个查询中,如果特定路径在遇到dm
节点之前需要超过100个步骤,那么您的查询将无法与之匹配。第二个查询在放弃寻找dm
之前会进行200步,因此它会找到更多路径。 (还有第二个问题:您的查询可以匹配多个dm
的路径,这可能不是您想要的。)
dm
中没有r2
节点(第一个节点除外)以下查询可能适合您的需求:
MATCH (i:interruption { ID:40 })-[:ON]->(p:pipe)-[r2:LINKED*..100]-(m)
WHERE ALL (r IN r2
WHERE NOT "dm" IN LABELS(ENDNODE(r)))
RETURN i, r2
LIMIT 200;
它使用单个MATCH
子句,并要求r2
中的任何节点(从其第二个节点开始)都没有dm
标签。 (此查询还会删除包含多个dm
个节点的路径。)
dm
节点仅被允许作为r2
此备用查询仅允许r2
中的(第一个和最后一个)节点为dm
:
MATCH (i:interruption { ID:40 })-[:ON]->(p:pipe)-[r2:LINKED*..100]-(m)
WHERE ALL (i IN RANGE(1, SIZE(r2)-2)
WHERE NOT "dm" IN LABELS(ENDNODE(r2[i])))
RETURN i, r2
LIMIT 200;