如何限制Cypher的遍历时间?

时间:2016-11-15 19:45:33

标签: neo4j cypher graph-databases

使用Cypher时,以下查询实际上将根据需要遍历所有可能的路径。

START n=node(0)
MATCH (n)-[]-(p1:Person)
RETURN n

但我想要的是:找到一个子图后停止遍历并返回结果告诉我它匹配。怎么做?就像LIMIT超过MATCH一样?但就我知道而言,LIMIT仅适用于RETURN而不是MATCH

1 个答案:

答案 0 :(得分:2)

如果您使用LIMIT,Neo4j会在找到匹配后停止遍历图表。

由于Cypher是一种声明性查询语言,查询优化器将正确处理LIMIT子句,即它将在模式匹配期间考虑限制。

让我们设计一个实验来证明这一点。示例数据集:

CREATE
  (p1:Person),
  (p2:Person),
  (p3:Person),
  (p1)-[:KNOWS]->(p2),
  (p1)-[:KNOWS]->(p3),
  (p2)-[:KNOWS]->(p3)

图表如下所示:

Example graph

首先,从查询中删除START子句,因为它将节点n绑定到特定的id,这不是我们想要进行此实验的内容。通常:START已被弃用,如果可能,您应该避免使用它。

让我们添加LIMIT 1约束,并使用PROFILE关键字来分析查询计划:

PROFILE
MATCH (n)-[]-(p1:Person)
RETURN n
LIMIT 1

Query plan with LIMIT 1

删除LIMIT关键字并再次分析查询计划:

PROFILE
MATCH (n)-[]-(p1:Person)
RETURN n

Query plan without LIMIT

如您所见,具有LIMIT 1约束的查询计划仅返回来自 NodeByLabelScan 操作的单行,具有2个数据库命中,而没有约束的查询计划返回3行有4个数据库命中。

根据InverseFalcon评论的建议

更新:,你也可以使用EXISTS函数,这将产生一个布尔值。但请注意,您仍然需要LIMIT 1才能在结果中获得一行(并避免不必要的数据库命中)。

PROFILE
MATCH (n)
RETURN EXISTS((n)-[]-(:Person))
LIMIT 1

enter image description here