入门
本节包含一个入门部分,涵盖使用 Cypher® 查询进行图模式匹配的一些基本功能。
示例图
本教程中使用的示例图是火车 Stations
的模型,以及在 Stations
停靠的不同火车服务 Stops
。
要重新创建该图,请对空的 Neo4j 数据库运行以下查询
CREATE (n1:Station {name: 'Denmark Hill'}),
(n5:Station {name: 'Battersea Park'}),
(n6:Station {name: 'Wandsworth Road'}),
(n15:Station {name: 'Clapham High Street'}),
(n16:Station {name: 'Peckham Rye'}),
(n17:Station {name: 'Brixton'}),
(n14:Station {name: 'London Victoria'}),
(n18:Station {name: 'Clapham Junction'}),
(p10:Stop {departs: time('22:37'), arrives: time('22:36')}),
(p0:Stop {departs: time('22:41'), arrives: time('22:41')}),
(p2:Stop {departs: time('22:43'), arrives: time('22:43')}),
(p17:Stop {arrives: time('22:50'), departs: time('22:50')}),
(p18:Stop {arrives: time('22:46'), departs: time('22:46')}),
(p19:Stop {departs: time('22:33'), arrives: time('22:31')}),
(p21:Stop {arrives: time('22:55')}),
(p20:Stop {departs: time('22:44'), arrives: time('22:43')}),
(p22:Stop {arrives: time('22:55')}),
(p23:Stop {arrives: time('22:48')}),
(n15)-[:LINK {distance: 1.96}]->(n1)-[:LINK {distance: 0.86}]->(n16),
(n15)-[:LINK {distance: 0.39}]->(n6)<-[:LINK {distance: 0.7}]-(n5)-[:LINK {distance: 1.24}]->(n14), (n5)-[:LINK {distance: 1.45}]->(n18),
(n14)<-[:LINK {distance: 3.18}]-(n17)-[:LINK {distance: 1.11}]->(n1),
(p2)-[:CALLS_AT]->(n6), (p17)-[:CALLS_AT]->(n5), (p19)-[:CALLS_AT]->(n16),
(p22)-[:CALLS_AT]->(n14), (p18)-[:CALLS_AT]->(n18), (p0)-[:CALLS_AT]->(n15), (p23)-[:CALLS_AT]->(n5), (p20)-[:CALLS_AT]->(n1),
(p21)-[:CALLS_AT]->(n14), (p10)-[:CALLS_AT]->(n1), (p19)-[:NEXT]->(p10)-[:NEXT]->(p0)-[:NEXT]->(p2)-[:NEXT]->(p23),
(p22)<-[:NEXT]-(p17)<-[:NEXT]-(p18), (p21)<-[:NEXT]-(p20)
匹配固定长度路径
一对空括号是一个 节点模式,它将匹配任何节点。此示例获取图中所有节点的计数
MATCH ()
RETURN count(*) AS numNodes
numNodes |
---|
|
行数:1 |
在节点模式中添加标签将过滤具有该标签的节点(请参阅 标签表达式)。以下查询获取所有具有标签 Stop
的节点的计数
MATCH (:Stop)
RETURN count(*) AS numStops
numStops |
---|
|
行数:1 |
路径模式 可以匹配关系以及它们连接的节点。以下查询获取所有停靠在 Denmark Hill
的火车的到达时间
MATCH (s:Stop)-[:CALLS_AT]->(:Station {name: 'Denmark Hill'})
RETURN s.arrives AS arrivalTime
arrivalTime |
---|
|
|
行数:2 |
路径模式可以包含内联 WHERE
子句。以下查询获取从 Denmark Hill
出发的 22:37
服务的下一个停靠点
MATCH (n:Station {name: 'Denmark Hill'})<-[:CALLS_AT]-
(s:Stop WHERE s.departs = time('22:37'))-[:NEXT]->
(:Stop)-[:CALLS_AT]->(d:Station)
RETURN d.name AS nextCallingPoint
nextCallingPoint |
---|
|
行数:1 |
有关更多信息,请参阅 固定长度模式.
匹配可变长度路径
仅遍历具有指定类型的关系的可变长度路径可以使用 量化关系 匹配。在关系模式中声明的任何变量都将返回遍历的关系列表。以下查询返回通过连接车站 Peckham Rye
和 Clapham Junction
的所有 LINK
行驶的总距离
MATCH (:Station {name: 'Peckham Rye'})-[link:LINK]-+
(:Station {name: 'Clapham Junction'})
RETURN reduce(acc = 0.0, l IN link | round(acc + l.distance, 2)) AS
totalDistance
totalDistance |
---|
|
|
行数:2 |
-[:LINK]-+ 是一个 量化关系。它由关系模式 -[:LINK]- 组成,它匹配任何方向的关系,以及量词 + ,它表示将匹配一个或多个关系。由于量化关系中不包含节点模式,因此它们将匹配任何中间节点。 |
可变长度路径也可以使用 量化路径模式 匹配,它允许 WHERE
子句以及访问路径遍历的节点。以下查询返回从 Peckham Rye
到 London Victoria
的路线上的停靠点列表,其中车站之间的距离不超过两英里
MATCH (:Station {name: 'Peckham Rye'})
(()-[link:LINK]-(s) WHERE link.distance <= 2)+
(:Station {name: 'London Victoria'})
UNWIND s AS station
RETURN station.name AS callingPoint
callingPoint |
---|
|
|
|
|
|
行数:5 |
节点模式内的 WHERE
子句本身可以包含路径模式。以下查询使用 EXISTS 子查询 锚定在 Stops
序列中的最后一个 Stop
上,并返回所有停靠在 Denmark Hill
的服务的出发时间、到达时间和最终目的地
MATCH (:Station {name: 'Denmark Hill'})<-[:CALLS_AT]-(s1:Stop)-[:NEXT]->+
(sN:Stop WHERE NOT EXISTS { (sN)-[:NEXT]->(:Stop) })-[:CALLS_AT]->
(d:Station)
RETURN s1.departs AS departure, sN.arrives AS arrival,
d.name AS finalDestination
departure | arrival | finalDestination |
---|---|---|
|
|
|
|
|
|
行数:2 |
在量化路径模式内声明的节点变量将绑定到节点列表,这些节点列表可以被展开并在后续 MATCH
子句中使用。以下查询列出了从 Peckham Rye
到 Battersea Park
火车服务的停靠点
MATCH (:Station {name: 'Peckham Rye'})<-[:CALLS_AT]-(:Stop)
(()-[:NEXT]->(s:Stop))+
()-[:CALLS_AT]->(:Station {name: 'Battersea Park'})
UNWIND s AS stop
MATCH (stop)-[:CALLS_AT]->(station:Station)
RETURN stop.arrives AS arrival, station.name AS callingPoint
arrival | callingPoint |
---|---|
|
|
|
|
|
|
|
|
行数:4 |
在路径模式中重复节点变量使同一个节点可以在路径中绑定多次(请参阅 等值连接)。以下查询找到所有由 Stations
之间的 LINK
形成的循环(即,通过同一个 Station
多次)中的车站
MATCH (n:Station)-[:LINK]-+(n)
RETURN DISTINCT n.name AS station
station |
---|
|
|
|
|
|
|
行数:6 |
可以使用 图模式 匹配复杂的非线性路径,图模式是通过重复的节点变量(即等值连接)连接的路径模式的逗号分隔列表。例如,一名乘客从 Denmark Hill
出发,想要搭乘从 Clapham Junction
出发的 22:46
到 London Victoria
的火车服务。以下查询找到从 Denmark Hill
出发的出发时间,以及换乘 Station
和到达时间
MATCH (:Station {name: 'Denmark Hill'})<-[:CALLS_AT]-
(s1:Stop)-[:NEXT]->+(s2:Stop)-[:CALLS_AT]->
(c:Station)<-[:CALLS_AT]-(x:Stop),
(:Station {name: 'Clapham Junction'})<-[:CALLS_AT]-
(t1:Stop)-[:NEXT]->+(x)-[:NEXT]->+(:Stop)-[:CALLS_AT]->
(:Station {name: 'London Victoria'})
WHERE t1.departs = time('22:46')
AND s2.arrives < x.departs
RETURN s1.departs AS departure, s2.arrives AS changeArrival,
c.name AS changeAt
departure | changeArrival | changeAt |
---|---|---|
|
|
|
行数:1 |
有关更多信息,请参阅 可变长度模式.
匹配最短路径
可以使用 SHORTEST
关键字查找两个节点之间的最短路径
MATCH p = SHORTEST 1
(:Station {name: "Brixton"})
(()-[:LINK]-(:Station))+
(:Station {name: "Clapham Junction"})
RETURN [station IN nodes(p) | station.name] AS route
route |
---|
|
行数:1 |
要查找所有最短路径,可以使用 ALL SHORTEST
关键字
MATCH p = ALL SHORTEST
(:Station {name: "Denmark Hill"})
(()-[:LINK]-(:Station))+
(:Station {name: "Clapham Junction"})
RETURN [station IN nodes(p) | station.name] AS route
route |
---|
|
|
行数:2 |
通常,SHORTEST k
可用于返回 k
个最短路径。以下返回两个最短路径
MATCH p = SHORTEST 2
(:Station {name: "Denmark Hill"})
(()-[:LINK]-(:Station))+
(:Station {name: "Clapham High Street"})
RETURN [station IN nodes(p) | station.name] AS route
route |
---|
|
|
行数:2 |
有关更多信息,请参阅 最短路径.