OPTIONAL MATCH
介绍
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
子句。
然而,用 OPTIONAL MATCH
替换第二个 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 |