如何在Cypher Neo4j中获取不包含具有特定属性的节点的所有节点

时间:2019-07-03 00:40:52

标签: database graph neo4j cypher nodes

在某些情况下,我需要查找不包含(关联)所有必需节点的节点。

我的业务逻辑如下:

* A Trajectory contains several Points.
* A Trajectory is complete when it has at least:
  * ONE Point START
  * ONE Point MIDDLE
  * ONE Point FINISH

在下面的示例中,我有4条轨迹

http://console.neo4j.org/?id=1fjeyl

一个轨迹是完整的,其他三个是不完整的。

如何找到不包含所有必需点的所有轨迹?

1 个答案:

答案 0 :(得分:1)

有几种方法可以做到这一点。

使用此模型,一种方法是您可以收集每个轨迹的节点,并使用列表谓词仅包括缺少任何所需位置的轨迹:

MATCH (t:Trajectory)-[:CONTAINS]->(p)
WITH t, collect(DISTINCT p.pos) as pointPositions
WHERE size(pointPositions) < 3 OR any(required in ['START', 'END', 'MIDDLE'] WHERE NOT required IN pointPositions)
RETURN t

请注意,如果重构模型以使点的位置改为由关系点指示,例如:

(:Trajectory)-[:HAS_START]->(:Point)
(:Trajectory)-[:HAS_END]->(:Point)
(:Trajectory)-[:HAS_MIDDLE]->(:Point)

然后,您的查询将变得更简单,效率也会提高(当您拥有许多轨迹时,其中一些具有许多连接的节点,这将显示最大的收益)。

MATCH (t:Trajectory)
WHERE NOT (t)-[:HAS_START]->() OR NOT (t)-[:HAS_END]->() OR NOT (t)-[:HAS_MIDDLE]->()
RETURN t

有了这种建模和这种查询,我们甚至不必从轨迹节点扩展出来就能得到答案,因为一个节点知道与之相关的关系(按类型和/或方向)及其数量。然后很容易确定是否存在某些关系类型。