入门

本节包含一个入门指南,涵盖了 Cypher® 查询中图模式匹配的一些基本功能。

示例图

本教程中使用的示例图是火车车站的模型,以及不同火车服务中在车站停靠的停靠点

patterns primer

要重新创建此图,请针对空的 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
表 1. 结果
numNodes

18

行数: 1

向节点模式添加标签将根据具有该标签的节点进行过滤(参见标签表达式)。以下查询获取所有带有标签Stop的节点的计数

MATCH (:Stop)
RETURN count(*) AS numStops
表 2. 结果
numStops

10

行数: 1

路径模式可以匹配关系以及它们连接的节点。以下查询获取所有在Denmark Hill停靠的火车的到达时间

MATCH (s:Stop)-[:CALLS_AT]->(:Station {name: 'Denmark Hill'})
RETURN s.arrives AS arrivalTime
表 3. 结果
arrivalTime

"22:36:00Z"

"22:43:00Z"

行数: 2

路径模式可以包含内联的WHERE子句。以下查询获取在22:37Denmark Hill发车的服务的下一个停靠点

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
表 4. 结果
nextCallingPoint

"Clapham High Street"

行数: 1

更多信息,请参阅固定长度模式

匹配可变长度路径

只遍历指定类型关系的可变长度路径可以使用量化关系进行匹配。关系模式中声明的任何变量都将返回遍历的关系列表。以下查询返回连接Peckham RyeClapham 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
表 5. 结果
totalDistance

7.84

5.36

行数: 2

-[:LINK]- 是一个 xref:patterns/reference.adoc#quantified-relationships[量化关系]。它由一个关系模式 -[:LINK]- 组成,该模式匹配任一方向的关系,以及一个量词 ,表示它将匹配一个或多个关系。由于量化关系中不包含节点模式,它们将匹配任何中间节点。

可变长度路径也可以通过量化路径模式进行匹配,后者允许使用WHERE子句并访问路径遍历的节点。以下查询返回从Peckham RyeLondon 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
表 6. 结果
callingPoint

"Denmark Hill"

"Clapham High Street"

"Wandsworth Road"

"Battersea Park"

"London Victoria"

行数: 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
表 7. 结果
departure arrival finalDestination

'22:37:00Z'

'22:48:00Z'

"Battersea Park"

'22:44:00Z'

'22:55:00Z'

"London Victoria"

行数: 2

在量化路径模式中声明的节点变量将绑定到节点列表,这些列表可以被解构并在后续的MATCH子句中使用。以下查询列出了Peckham RyeBattersea 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
表 8. 结果
arrival callingPoint

"22:36:00Z"

"Denmark Hill"

"22:41:00Z"

"Clapham High Street"

"22:43:00Z"

"Wandsworth Road"

"22:48:00Z"

"Battersea Park"

行数: 4

在路径模式中重复节点变量可以使同一节点在路径中多次绑定(参见等值连接)。以下查询查找所有通过Stations之间的LINK形成环(即多次经过同一Station)的车站

查询
MATCH (n:Station)-[:LINK]-+(n)
RETURN DISTINCT n.name AS station
表 9. 结果
station

"Denmark Hill"

"Battersea Park"

"Wandsworth Road"

"Clapham High Street"

"Brixton"

"London Victoria"

行数: 6

复杂的非线性路径可以使用图模式进行匹配,图模式是由逗号分隔的路径模式列表,这些模式通过重复的节点变量(即等值连接)连接。例如,一位乘客从Denmark Hill出发,想搭乘22:46Clapham Junction发往London Victoria的火车服务。以下查询查找从Denmark Hill出发的时间以及换乘车站和到达时间

查询
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
表 10. 结果
departure changeArrival changeAt

"22:37:00Z"

"22:48:00Z"

"Battersea Park"

行数: 1

更多信息,请参阅可变长度模式

匹配最短路径

可以使用SHORTEST关键字查找两个节点之间的最短路径

查询
MATCH p = SHORTEST 1
  (:Station {name: "Brixton"})
  (()-[:LINK]-(:Station))+
  (:Station {name: "Clapham Junction"})
RETURN [station IN nodes(p) | station.name] AS route
表 11. 结果
route

["Brixton", "London Victoria", "Battersea Park", "Clapham Junction"]

行数: 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
表 12. 结果
route

["Denmark Hill", "Clapham High Street", "Wandsworth Road", "Battersea Park", "Clapham Junction"]

["Denmark Hill", "Brixton", "London Victoria", "Battersea Park", "Clapham Junction"]

行数: 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
表 13. 结果
route

["Denmark Hill", "Clapham High Street"]

["Denmark Hill", "Brixton", "London Victoria", "Battersea Park", "Wandsworth Road", "Clapham High Street"]

行数: 2

更多信息,请参阅最短路径

© . All rights reserved.