首页 > 解决方案 > 如何在 Cypher Neo4j 中获取不包含(相关)具有特定属性的节点的所有节点

问题描述

我有一个案例,我需要找到不包含(相关)所有必需节点的节点。

我的业务逻辑如下:

* 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

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

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

标签: databasegraphneo4jcyphernodes

解决方案


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

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

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

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


推荐阅读