路径模式表达式

EXISTS 子查询类似,路径模式表达式可用于断言指定的路径在图中是否至少存在一次。虽然存在性子查询功能更强大,能够执行路径模式表达式所能实现的所有操作,但路径模式表达式更为简洁。

有关 Cypher® 中图模式匹配的更多信息,请参阅 模式

规则

路径模式表达式具有以下限制(需要扩展功能的用例应考虑改用 存在性子查询):

  • 路径模式表达式只能使用 图模式 语义的一个子集。

  • 路径模式表达式必须是长度大于零的 路径模式。换句话说,它必须至少包含一个 关系可变长度关系

  • 路径模式表达式不能声明新变量。它们只能引用现有的变量。

  • 路径模式表达式只能用在预期使用 布尔表达式 的位置。以下章节将演示如何在 WHERE 子句中使用路径模式表达式。

示例图

以下图表用于下方的示例

要重建该图,请在空的 Neo4j 数据库中运行以下查询

CREATE (alice:Person {name:'Alice', age: 65, role: 'Project manager'}),
       (cecil:Person {name: 'Cecil', age: 25, role: 'Software developer'}),
       (cecilia:Person {name: 'Cecilia', age: 31, role: 'Software developer'}),
       (cecil)-[:WORKS_FOR {since: 2023}]->(alice),
       (cecilia)-[:WORKS_FOR {since: 2015}]->(alice)

示例

简单路径模式表达式
MATCH (employee:Person)
WHERE (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
RETURN employee.name AS employee
结果
employee

"Cecil"

"Cecilia"

行:2

包含布尔运算符 NOTAND 的路径模式表达式
MATCH (employee:Person)
WHERE NOT employee.name = 'Cecil' AND (employee)-[:WORKS_FOR]->(:Person {name: 'Alice'})
RETURN employee.name AS employee
结果
employee

"Cecilia"

行:1

有关 Cypher 布尔运算符的更多信息,请参阅 谓词表达式 → 布尔运算符

模式可以放置在表达式内部。

表达式内部的模式
RETURN NOT (:Person {name: "Alice"})<-[:WORKS_FOR {since: 2023}]-(:Person) AS patternCheck
结果
patternCheck

false

行:1

在上述示例中,需要使用 NOT 才能使查询成为有效的谓词表达式。如果没有它,该查询将无效,因为该表达式不会返回 BOOLEAN 值。

exists() 函数可用于检查模式是否存在。请注意,此函数的功能不如 EXISTS 子查询通用。

使用 exists() 函数检查模式是否存在
RETURN exists((:Person)-[:WORKS_FOR {since: 2023}]->(:Person {name: "Alice"})) AS patternCheck
结果
patternCheck

TRUE

行:1

类似于路径模式表达式的表达式

由于任何表达式都可以用括号括起来,因此有些表达式与路径模式表达式非常相似。例如:

(p:Person) 不是路径模式表达式,因为它没有至少一个 关系可变长度关系。相反,(p:Person) 是括号中的 标签表达式谓词 p:Person

括号括起来的标签表达式谓词
MATCH (employee:Person)-[:WORKS_FOR]->(p)
  WHERE (p:Person)
RETURN employee.name AS employee, (p:Person) AS workForAPeron

然而,p:Person(p:Person) 的查询结果是相同的。

MATCH (employee:Person)-[:WORKS_FOR]->(p)
  WHERE p:Person
RETURN employee.name AS employee, p:Person AS workForAPerson
结果
employee workForAPerson

"Cecil"

true

"Cecilia"

true

行:2

(p) 不是路径模式表达式,因为它没有至少一个 关系可变长度关系。相反,(p) 是括号中的变量 p

(p) 的确会产生变量 p 的值。如果 p 不是布尔值,则 (p) 也不会产生布尔值。因此,以下查询会抛出错误。

括号括起来的节点变量
MATCH (employee:Person)-[:WORKS_FOR]->(p)
  WHERE (p)
RETURN employee.name AS employee
Invalid input 'Node' for `p`. Expected to be Boolean.