WHERE

WHERE 子句本身不是一个独立的子句,而是与 MATCHOPTIONAL MATCHWITH 子句配合使用的从句。

当与 MATCHOPTIONAL MATCH 一起使用时,WHERE 会为所描述的模式添加约束。它不应被视为匹配完成后的过滤器。

在存在多个 MATCH / OPTIONAL MATCH 子句的情况下,WHERE 中的谓词始终是紧邻其前的 MATCH / OPTIONAL MATCH 模式的一部分。如果将 WHERE 放置在错误的 MATCH 子句中,可能会影响结果和性能。

当在 WITH 之后使用时,WHERE 仅用于过滤结果。

有关 WHERE 的更多用法,请参阅谓词 (Predicates)

示例图

以下图表用于下方的示例

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

CREATE (andy:Swedish:Person {name: 'Andy', age: 36}),
       (timothy:Person {name: 'Timothy', age: 38}),
       (peter:Person {name: 'Peter', age: 35}),
       (lisa:Person {name: 'Lisa', age: 48}),
       (john:Person {name: 'John', age: 40}),
       (susan:Person {name: 'Susan', age: 32}),
       (andy)-[:KNOWS {since: 2012}]->(timothy),
       (andy)-[:KNOWS {since: 1999}]->(peter),
       (peter)-[:KNOWS {since: 2005}]->(lisa),
       (lisa)-[:KNOWS {since: 2010}]->(john),
       (john)-[:KNOWS {since: 2021}]->(susan)

基本过滤

对节点标签进行过滤
MATCH (n)
WHERE n:Swedish
RETURN n.name AS name
结果
名称 (name)

"Andy"

行:1

对节点属性进行过滤
MATCH (n:Person)
WHERE n.age < 35
RETURN n.name AS name, n.age AS age
结果
名称 (name) age

"Susan"

32

行:1

对关系属性进行过滤
MATCH (:Person {name:'Andy'})-[k:KNOWS]->(f)
WHERE k.since < 2000
RETURN f.name AS oldFriend
结果
oldFriend

"Peter"

行:1

对动态标签和类型进行过滤

若要使用动态计算的值来过滤标签或关系类型,请使用 $(<expr>),其中 <expr> 为任何 Cypher® 表达式

参数
{
  "label": "Swedish"
}
对动态计算的节点标签进行过滤
MATCH (n)
WHERE n:$($label)
RETURN labels(n) AS labels
结果
标签

["Person", "Swedish"]

行:1

对动态属性进行过滤

若要使用动态计算的名称来过滤属性,请使用方括号 []

参数
{
  "propname": "age"
}
对动态计算的节点属性进行过滤
MATCH (n:Person)
WHERE n[$propname] > 40
RETURN n.name AS name, n.age AS age
结果
名称 (name) age

"Lisa"

48

行:1

WITH 之后使用 WHERE

WITH 可用于在将子句输出传递给后续查询部分之前对其进行处理。一旦进行了这种处理,原始子句的输出将无法被后续子句访问。例如,在下面的查询中,WITH 处理了前一个 MATCH 的输出,使得随后的 RETURN 无法再访问 MATCH 中声明的变量 n

WITH 仅保留显式列出的变量;其他变量将无法访问
MATCH (n:Person)
WITH n.name as name
RETURN n

如果 RETURN 子句引用的是 WITH 产生的 name 变量,则上述查询可以正常工作。然而,由于 WHERE 是一个从句而非独立子句,其作用域不受紧邻其前的 WITH 子句限制。

WHERE 不受紧邻其前的 WITH 限制
MATCH (n:Person)
WITH n.name as name
WHERE n.age = 38
RETURN name
结果
名称 (name)

"Timothy"

行:1

返回了 Timothy 的名字,因为 WHERE 子句仍然充当 MATCH 的过滤器。然而,WITH 确实缩小了查询后续部分的作用域。在本例中,nameRETURN 子句作用域内唯一的变量。

过滤模式

WHERE 子句可以添加到定长变长模式中,以指定额外的约束。

定长模式

节点模式内的 WHERE
WITH 35 AS minAge
MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
RETURN b.name AS name
结果
名称 (name)

"Timothy"

行:1

以这种方式使用时,WHERE 中的谓词可以引用该 WHERE 子句所属的节点变量,但不能引用 MATCH 模式中的其他元素。

同样的规则适用于模式推导 (pattern comprehensions)

模式推导内的 WHERE
MATCH (a:Person {name: 'Andy'})
RETURN [(a)-->(b WHERE b:Person) | b.name] AS friends
结果
friends

["Peter","Timothy"]

行:1

WHERE 也可以出现在 MATCH 子句的关系模式中

关系模式内的 WHERE
WITH 2000 AS minYear
MATCH (a:Person)-[r:KNOWS WHERE r.since < minYear]->(b:Person)
RETURN a.name AS person, b.name AS friend, r.since AS knowsSince
结果
名称 (name) friend knowsSince

"Andy"

"Peter"

1999

行:1

关系模式谓词也可以在模式推导中使用,且适用相同的注意事项

模式推导内的关系模式谓词
WITH 2000 AS minYear
MATCH (a:Person {name: 'Andy'})
RETURN [(a)-[r:KNOWS WHERE r.since < minYear]->(b:Person) | r.since] AS years
结果
years

[1999]

行:1

变长模式

如果匹配变长模式,WHERE 只能与量化路径模式量化关系语法一起使用。

允许 - 量化关系内的 WHERE 谓词
MATCH p = (a:Person {name: "Andy"})-[r:KNOWS WHERE r.since < 2011]->{1,4}(:Person)
RETURN [n IN nodes(p) | n.name] AS paths

请注意,任何包含 TimothySusan 的路径都被 WHERE 谓词排除了,因为它们传入的 KNOWS 关系的 since 值都大于 2011

结果
paths

["Andy", "Peter"]

["Andy", "Peter", "Lisa"]

["Andy", "Peter", "Lisa", "John"]

行:3

有关在量化路径模式中使用 WHERE 谓词的更多信息,请参阅量化路径模式中的谓词

在不兼容 GQL 的变长关系语法中,不允许使用 WHERE

不允许 - 变长关系内的 WHERE
MATCH p = (a:Person {name: 'Andy'})-[r:KNOWS*1..4 WHERE r.since < 2011]->(b:Person)
RETURN [n IN nodes(p) | n.name] AS path