FILTER仅限 Cypher 25Neo4j 2025.06 引入
FILTER 用于向查询中添加过滤条件,类似于 Cypher® 的 WHERE。与 WHERE 不同,FILTER 不是子句,这意味着它可以独立于 MATCH、OPTIONAL MATCH 和 WITH 子句使用,但不能在它们内部使用。
示例图
以下图表用于下方的示例
要重建该图,请在空的 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)
FILTER n:Swedish
RETURN n.name AS name
| 名称 (name) |
|---|
|
|
MATCH (n:Person)
FILTER n.age < 35
RETURN n.name AS name, n.age AS age
| 名称 (name) | age |
|---|---|
|
|
|
|
MATCH (p:Person)-[r:KNOWS]->(n:Person)
FILTER r.since > 2010
RETURN p.name AS person,
r.since AS knowsSince,
n.name AS otherPerson
| person | knowsSince | otherPerson |
|---|---|---|
|
|
|
|
|
|
|
||
基于动态标签和类型过滤
若要使用动态计算的值来过滤标签或关系类型,请使用 $(<expr>),其中 <expr> 是任何 Cypher 表达式
{
"label": "Swedish"
}
MATCH (n)
FILTER n:$($label)
RETURN labels(n) AS labels
| 标签 |
|---|
|
行:1 |
基于动态属性过滤
若要使用动态计算的名称来过滤属性,请使用方括号 []
{
"propname": "age"
}
MATCH (n:Person)
FILTER n[$propname] > 40
RETURN n.name AS name, n.age AS age
| 名称 (name) | age |
|---|---|
|
|
行:1 |
|
FILTER 与 WHERE 的区别
FILTER 和 WHERE 都用于向查询应用过滤。然而,由于 FILTER 是一个子句,而 WHERE 是一个子句(subclause,意指从属子句),两者之间存在一些重要区别。
-
FILTER在实体被匹配之后起作用,而WHERE在匹配执行之前限制哪些行会被匹配。 -
FILTER不能在MATCH、OPTIONAL MATCH或WITH子句中使用,只能与它们并列使用。这意味着,与WHERE不同,FILTER不能用于在模式内部添加过滤条件。
FILTER 与 WHERE 的区别此 OPTIONAL MATCH 示例强调了 WHERE 子句与 FILTER 子句之间的差异。
WHERE 约束 OPTIONAL MATCH 模式UNWIND [32,37,40] AS ageValue
OPTIONAL MATCH (p:Person)
WHERE p.age = ageValue
RETURN p.name AS name, p.age AS age
| 名称 (name) | age |
|---|---|
|
|
|
|
|
|
行:3 |
|
由于 WHERE 是属于 OPTIONAL MATCH 的从属子句,它仅过滤匹配项,但不影响返回的行数。在此例中,OPTIONAL MATCH 始终保留来自 UNWIND 的所有行,且 WHERE 不会移除任何返回 NULL 的行。如果将 WHERE 替换为 FILTER,情况则不同。
FILTER 为 OPTIONAL MATCH 添加后过滤UNWIND [32,37,40] AS ageValue
OPTIONAL MATCH (p:Person)
FILTER p.age = ageValue
RETURN p.name AS name, p.age AS age
| 名称 (name) | age |
|---|---|
|
|
|
|
行:2 |
|
与 WHERE 不同,FILTER 不是 OPTIONAL MATCH 的一部分,因此会根据表达式中提供的条件从结果集中移除整行。即,当 OPTIONAL MATCH 未能找到匹配项且 p 为 NULL 时,无法对 FILTER p.age = ageValue 进行求值,导致整行被移除。
FILTER 不能在模式内部使用由于 WHERE 是限定所描述模式的从属子句,因此它可以用在模式内部。
WHEREWITH 35 AS minAge
MATCH (a:Person WHERE a.name = 'Andy')-[:KNOWS]->(b:Person WHERE b.age > minAge)
RETURN b.name AS name
| 名称 (name) |
|---|
|
行:1 |
对于 FILTER 来说并非如此,作为一个子句,它不能放置在模式中。
FILTERWITH 35 AS minAge
MATCH (a:Person FILTER a.name = 'Andy')-[:KNOWS]->(b:Person FILTER b.age > minAge)
RETURN b.name AS name
有关如何在固定长度和可变长度模式匹配中使用 WHERE 的更多信息,请参阅 WHERE → 过滤模式。
FILTER 作为 WITH * WHERE 的替代方案
与依赖 MATCH、OPTIONAL MATCH 或 WITH 来定义作用域的 WHERE 不同,FILTER 可以独立于这些子句过滤查询。这可以使某些查询更加简洁。
例如,以下两个查询是等效的
WITH * WHERE 进行过滤UNWIND [1, 2, 3, 4, 5, 6] AS x
WITH x
WHERE x > 2
RETURN x
FILTER 进行过滤UNWIND [1, 2, 3, 4, 5, 6] AS x
FILTER x > 2
RETURN x
因此,FILTER 可以被视为 Cypher 中 WITH * WHERE <predicate> 结构的替代方案。
LOAD CSV 中使用 FILTER 代替 WITH * WHERE以下两个 LOAD CSV 命令是等效的
Id,Name,Location,Email,BusinessType
1,Neo4j,San Mateo,contact@neo4j.com,P
2,AAA,,info@aaa.com,
3,BBB,Chicago, info@ ,G
,CCC,Michigan,info@ccc.com,G
WITH * WHERE 的 LOAD CSVLOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row
WHERE row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
FILTER 的 LOAD CSVLOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
FILTER row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
然而,尽管 FILTER 可以作为 WITH * WHERE <predicate> 结构的替代方案,但它不具备 WITH 对后续子句中的变量进行操作的能力。FILTER 也不能重命名(alias)或创建新变量。换句话说,FILTER 仅具备 WITH * WHERE <predicate> 的功能,而不具备 WITH <selectedVariable> AS <newVariableName> WHERE <predicate> 的功能。