使用特定传递节点标签过滤掉路径时的奇怪Cypher行为

时间:2017-05-30 15:33:47

标签: neo4j cypher

给出带有Activity(蓝色节点)和Gateway(大多数灰色节点)的图表 enter image description here 当我执行查询时(activitiNodeId是名为“Notify host regulator”的节点):

MATCH p =(cur:Activity {projectId: '13', activitiNodeId: 'sid-84FC0D7F-9683-4D63-A2EA-A3ABB2AD10AE_0_null'})-[r:PRECEDES*]->(next)
WHERE ANY (label IN labels(next) WHERE label IN ['Activity', 'End']) 
AND NOT (cur)-[:PRECEDES*]->(:Activity)-[:PRECEDES*]->(next)
RETURN p

我希望得到以下子图(因为条件NOT (cur)-[:PRECEDES*]->(:Activity)-[:PRECEDES*]->(next)表示我希望在Activity和{{1}之间的路径中找到所有类型cur的节点都没有的路径}}):

enter image description here

但由于某种原因,我得到了这个(它在next个节点之间有2个Gateway个节点时拒绝路径):

enter image description here

我设法通过手动计算每条路径中的节点来实现我想要的结果:

Activity

因为this issue,我将neo4j 3.2与MATCH p =(cur:Activity {projectId: '13', activitiNodeId: 'sid-84FC0D7F-9683-4D63-A2EA-A3ABB2AD10AE_0_null'})-[r:PRECEDES*]->(next) WHERE ANY (label IN labels(next) WHERE label IN ['Activity', 'End']) AND SIZE(FILTER(x IN REDUCE(s = [], x IN EXTRACT(n IN NODES(p) | LABELS(n)) | s + x) WHERE x = 'Activity' OR x = 'End')) < 3 RETURN p 一起使用。 有人可以解释一下这个Cypher的行为吗?

2 个答案:

答案 0 :(得分:1)

WHERE NOT (cur)-[:PRECEDES*]->(:Activity)-[:PRECEDES*]->(next)实际上意味着&#34; curnext之间存在无路径,其中包含Activity节点&#34;

尽管您的预期结果包含3个此类中间Activity节点,但实际结果中没有中间Activity个节点。

[增订]

下面的查询应该&#34;找到Activitycur&#34;之间路径中任何类型next的节点都没有的所有路径。 NONE函数用于过滤掉具有中间Activity个节点的所有路径。请注意,我还简化了标签测试。

MATCH p =(cur:Activity {projectId: '13', activitiNodeId: 'sid-84FC0D7F-9683-4D63-A2EA-A3ABB2AD10AE_0_null'})-[:PRECEDES*]->(next)
WHERE
  (next:Activity OR next:End) AND
  NONE(n IN NODES(p)[1..-1] WHERE n:Activity)
RETURN p;

上述查询的结果与您明显错误的&#34;期望&#34;图表,因为您的预期图表包含具有中间Activity个节点的3条路径。

答案 1 :(得分:1)

以下是您的查询细目

// Matches start_node | pathof0+_relationships | end_node
MATCH p =(cur:Activity {projectId: '13', activitiNodeId: 'sid-84FC0D7F-9683-4D63-A2EA-A3ABB2AD10AE_0_null'})-[r:PRECEDES*]->(next)

// Where end_node is an Activity or End
WHERE ANY (label IN labels(next) WHERE label IN ['Activity', 'End'])

// And there exists no path from start to end that has an activity between them
AND NOT (cur)-[:PRECEDES*]->(:Activity)-[:PRECEDES*]->(next)
RETURN p

请注意,最后一次检查是“如果 A 路径存在”而不是“如果此路径包含”。因为远程节点存在路径,所以它的所有路径都会被过滤掉。

在您更正的查询中,您实际上正在检查“此路径中是否有任何节点”(路径p变量的迭代),这就是它有不同结果的原因。