可选匹配
介绍
OPTIONAL MATCH
与 MATCH
一样,将模式与图数据库匹配。区别在于,如果没有找到匹配项,OPTIONAL MATCH
将对模式的缺失部分使用 null
。因此,OPTIONAL MATCH
可以被认为是 Cypher® 中的 SQL 外连接等效项。
使用 OPTIONAL MATCH
时,要么整个模式匹配,要么不匹配。WHERE
子句是模式描述的一部分,其谓词将在查找匹配项时被考虑,而不是之后。这在多个 (OPTIONAL
) MATCH
子句的情况下尤其重要,因为将 WHERE
与其所属的 MATCH
放在一起至关重要。
要了解 |
示例图
以下图用于下面的示例
要重新创建该图,请在空的 Neo4j 数据库中运行以下查询
CREATE
(charlie:Person {name: 'Charlie Sheen'}),
(martin:Person {name: 'Martin Sheen'}),
(michael:Person {name: 'Michael Douglas'}),
(oliver:Person {name: 'Oliver Stone'}),
(rob:Person {name: 'Rob Reiner'}),
(wallStreet:Movie {title: 'Wall Street'}),
(charlie)-[:ACTED_IN]->(wallStreet),
(martin)-[:ACTED_IN]->(wallStreet),
(michael)-[:ACTED_IN]->(wallStreet),
(oliver)-[:DIRECTED]->(wallStreet),
(thePresident:Movie {title: 'The American President'}),
(martin)-[:ACTED_IN]->(thePresident),
(michael)-[:ACTED_IN]->(thePresident),
(rob)-[:DIRECTED]->(thePresident),
(martin)-[:FATHER_OF]->(charlie)
更详细的 OPTIONAL MATCH
与 SQL 一样,Cypher 查询使用各种子句构建,这些子句链接在一起,在每个子句之间传递中间结果。例如,来自一个 MATCH
子句的匹配变量将提供下一个子句存在的上下文。但是,Neo4j 和 SQL 之间存在两个重要区别,这有助于进一步解释 OPTIONAL MATCH
。
-
虽然使用索引和约束来强制执行部分模式是可能的也是建议的,但 Neo4j 提供比关系数据库更高的模式灵活性。Neo4j 数据库中的节点和关系不需要具有特定的属性集,因为同一图中的其他节点或关系具有该属性(除非在特定属性上创建了 属性存在约束)。
-
Cypher 中的查询作为管道运行。如果一个子句没有返回任何结果,它实际上将结束查询,因为后续子句将没有数据可供执行。
例如,以下查询没有返回任何结果
MATCH (a:Person {name: 'Martin Sheen'})
MATCH (a)-[r:DIRECTED]->()
RETURN a.name, r
(no changes, no records)
这是因为第二个 MATCH
子句没有返回任何数据(图中没有连接到 Martin Sheen
的 DIRECTED
关系),因此无法传递到 RETURN
子句。
但是,将第二个 MATCH
子句替换为 OPTIONAL MATCH
会返回结果。这是因为,与 MATCH
不同,OPTIONAL MATCH
允许在子句之间传递 null
值。
MATCH (p:Person {name: 'Martin Sheen'})
OPTIONAL MATCH (p)-[r:DIRECTED]->()
RETURN p.name, r
p.name | r |
---|---|
|
|
行数:1 |
因此,OPTIONAL MATCH
可用于检查图中是否存在缺失值和现有值,并将没有任何数据的行传递给查询中的后续子句。
可选关系
如果关系的存在是可选的,请使用 OPTIONAL MATCH
子句。如果关系存在,则返回该关系。如果不存在,则返回 null
。
MATCH (a:Movie {title: 'Wall Street'})
OPTIONAL MATCH (a)-->(x)
RETURN x
返回 null
,因为 Movie
节点 Wall Street
没有传出关系。
x |
---|
|
行数:1 |
另一方面,以下查询不会返回 null
,因为 Person
节点 Charlie Sheen
具有一个传出关系。
MATCH (a:Person {name: 'Charlie Sheen'})
OPTIONAL MATCH (a)-->(x)
RETURN x
x |
---|
|
行数:2 |
可选元素上的属性
如果属性的存在是可选的,请使用 OPTIONAL MATCH
子句。如果指定的属性不存在,则返回 null
。
MATCH (a:Movie {title: 'Wall Street'})
OPTIONAL MATCH (a)-->(x)
RETURN x, x.name
返回元素 x
(此查询中的 null
),以及其 name
属性的 null
,因为 Movie
节点 Wall Street
没有传出关系。
x | x.name |
---|---|
|
|
行数:1 |
以下查询仅对缺少 name
属性的节点返回 null
。
MATCH (a:Person {name: 'Martin Sheen'})
OPTIONAL MATCH (a)-->(x)
RETURN x, x.name
x | x.name |
---|---|
|
|
|
|
|
|
行数:3 |
可选类型和命名关系
使用 OPTIONAL MATCH
时,也可以查找特定关系类型
MATCH (a:Movie {title: 'Wall Street'})
OPTIONAL MATCH (a)-[r:ACTED_IN]->()
RETURN a.title, r
这将返回 Movie
节点 Wall Street
的标题,并且由于该节点没有传出 ACTED_IN
关系,因此对于变量 r
表示的关系返回 null
。
a.title | r |
---|---|
|
|
行数:1 |
但是,以下查询不会返回 null
,因为它正在查找 Movie
节点 Wall Street
的传入 ACTED_IN
类型的关系。
MATCH (a:Movie {title: 'Wall Street'})
OPTIONAL MATCH (x)-[r:ACTED_IN]->(a)
RETURN a.title, x.name, type(r)
a.title | x.name | type(r) |
---|---|---|
|
|
|
|
|
|
|
|
|
行数:3 |