匹配节点与具有参数的相关节点或没有相关节点

时间:2017-09-30 04:41:43

标签: neo4j cypher

我在查询以匹配以下数据时遇到问题:

假设我们在数据库中有以下节点

CREATE (:FOO{y:1,x:1.0})
CREATE (:FOO{y:1,x:2.0})
CREATE (:FOO{y:1,x:3.0})
CREATE (:FOO{y:1,x:4.0})
CREATE (:FOO{y:1,x:5.0})
CREATE (:DERP{y:1,x:2.5})
CREATE (:DERP{y:1,x:6.0})

节点由[:BAR]以x的升序连接。所以图表看起来像

(:FOO{x:1.0})-[:BAR]->(:FOO{x:2.0})-[:BAR]->(:FOO{x:3.0})-[:BAR]->(:FOO{x:4.0})-[:BAR]->(:FOO{x:5.0})

问题是为:DERP节点创建[:BAR]关系。它们应该相关,使得(p:FOO) - [:BAR] - >(q:DERP)其中px< = qx AND(p:FOO) - [:BAR] - >(n:FOO)其中nx> q.x或其中p.x< = q.x AND NOT(p:FOO) - [:BAR] - >()

试着用另一种方式,我们有:FOO节点按关系连接:BAR和:DERP节点应链接到:FOO节点,x小于或等于:DERP {x}其中下一个节点相关者:BAR的x大于:DERP {x}

所以最后我们有

                                    __[:BAR]->(:DERP{y:1,x:2.5})
                                   /
(:FOO{x:1.0})-[:BAR]->(:FOO{x:2.0})-[:BAR]->(:FOO{x:3.0})-[:BAR]->(:FOO{x:4.0})-[:BAR]->(:FOO{x:5.0})->[:BAR]-(:DERP{y:1,x:6.0})

我的尝试解决方案失败了......我可以得到它:DERP {y:2.5}以下

MATCH (a:DERP{y:1,x:2.5})
MATCH (p:FOO{y:1})-[:BAR]->(q:FOO{y:1})
WHERE p.x <= a.x AND q.x > a.x
CREATE (p)-[:BAR]->(a)

但是在p是链中的最后一个节点的情况下失败了,因为没有q:FOO匹配。所以我的下一次尝试是尝试可选的匹配

 MATCH (a:DERP{y:1,x:6.0})
 MATCH (p:FOO{y:1})
    WHERE p.x <= a.x
 OPTIONAL MATCH (p)-[:BAR]->(q:FOO{y:1})
    WHERE (p.x <= a.x AND q.x > a.x) OR q IS NULL
 CREATE (p)-[:BAR]->(a)

我想我理解为什么这不起作用..但我似乎无法自己解决问题。感谢任何帮助,并为长篇文章道歉我不太确定如何解释它,我不能发布真实数据的例子。

1 个答案:

答案 0 :(得分:0)

您的上一个查询无效的原因是因为您在OPTIONAL MATCH上有WHERE子句,因此它不会过滤掉行。

请记住,OPTIONAL MATCH不会过滤掉不匹配的行,它会将新引入的变量(在本例中为q)设置为null。 WHERE子句与前面的子句(MATCH,WITH或OPTIONAL MATCH)配对,如果您希望它过滤掉行,则必须将它与MATCH或WITH配对。

有关详细信息,请查看this Neo4j knowledge base article的顶部部分,了解您的where子句似乎无效的原因。

所以你需要的是你的OPTIONAL MATCH和WHERE之间的WITH:

MATCH (a:DERP{y:1,x:6.0})
 MATCH (p:FOO{y:1})
    WHERE p.x <= a.x
 OPTIONAL MATCH (p)-[:BAR]->(q:FOO{y:1})
 WITH a, p, q
    WHERE (p.x <= a.x AND q.x > a.x) OR q IS NULL
 CREATE (p)-[:BAR]->(a)

现在,如果您想要一个适用于所有节点的更通用的查询,请尝试以下方法:

MATCH (f:FOO)
OPTIONAL MATCH (f)-[:BAR]->(ff:FOO)
WITH f, f.x as lower, ff.x as upper
MATCH (d:DERP)
WHERE lower <= d.x and (upper is null or d.x <= upper)
CREATE (f)-[:BAR]->(d)