MATCH

MATCH语句提供基于模式(pattern)匹配的搜索功能。

一个MATCH语句定义了一个搜索模式,用该模式匹配存储在Nebula Graph中的数据,然后用RETURN子句检索数据。

本文示例使用测试数据库basketballplayer进行演示。

语法

GOLOOKUP等其他查询语句相比,MATCH的语法更灵活。MATCH语法可以概括如下:

  1. MATCH <pattern> [<WHERE clause>] RETURN <output>

MATCH工作流程

  1. MATCH语句使用原生索引查找起始点,起始点可以在模式的任何位置。即一个有效的MATCH语句,必须有一个属性、标签或者点已经创建索引。如何创建索引,请参见创建原生索引

  2. MATCH语句在模式中搜索,寻找匹配的边或点。

  3. MATCH语句根据RETURN子句检索数据。

openCypher兼容性

nGQL暂不支持遍历所有点和边,例如MATCH (v) RETURN v

使用模式(pattern)

前提条件

请确保MATCH语句有至少一个索引可用。如果您需要创建索引,但是已经有相关的点、边或属性,您必须在创建索引后重建索引,索引才能生效。

警告:正确使用索引可以加快查询速度,但是索引会导致写性能大幅降低(降低90%甚至更多)。请不要随意在生产环境中使用索引,除非您很清楚使用索引对业务的影响。

  1. # 在属性name上创建索引。
  2. nebula> CREATE TAG INDEX name ON player(name(20));
  3. # 重建索引使其生效。
  4. nebula> REBUILD TAG INDEX name;
  5. +------------+
  6. | New Job Id |
  7. +------------+
  8. | 121 |
  9. +------------+
  10. # 确认重建索引成功。
  11. nebula> SHOW JOB 121;
  12. +----------------+---------------------+------------+------------+------------+
  13. | Job Id(TaskId) | Command(Dest) | Status | Start Time | Stop Time |
  14. +----------------+---------------------+------------+------------+------------+
  15. | 121 | "REBUILD_TAG_INDEX" | "FINISHED" | 1607073046 | 1607073046 |
  16. +----------------+---------------------+------------+------------+------------+
  17. | 0 | "storaged2" | "FINISHED" | 1607073046 | 1607073046 |
  18. +----------------+---------------------+------------+------------+------------+
  19. | 1 | "storaged0" | "FINISHED" | 1607073046 | 1607073046 |
  20. +----------------+---------------------+------------+------------+------------+
  21. | 2 | "storaged1" | "FINISHED" | 1607073046 | 1607073046 |
  22. +----------------+---------------------+------------+------------+------------+

匹配点

您可以在一对括号中使用自定义变量来表示模式中的点。例如(v)

匹配标签

说明:标签的索引和属性的索引不同。如果标签的某个属性有索引,但是标签本身没有索引,您无法基于该标签执行MATCH语句。

您可以在点的右侧用:<tag_name>表示模式中的标签。

  1. nebula> MATCH (v:player) RETURN v;
  2. +---------------------------------------------------------------+
  3. | v |
  4. +---------------------------------------------------------------+
  5. | ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
  6. +---------------------------------------------------------------+
  7. | ("player106" :player{age: 25, name: "Kyle Anderson"}) |
  8. +---------------------------------------------------------------+
  9. | ("player115" :player{age: 40, name: "Kobe Bryant"}) |
  10. +---------------------------------------------------------------+
  11. ...

匹配点的属性

您可以在标签的右侧用{<prop_name>: <prop_value>}表示模式中点的属性。

  1. # 使用属性name搜索匹配的点。
  2. nebula> MATCH (v:player{name:"Tim Duncan"}) RETURN v;
  3. +----------------------------------------------------+
  4. | v |
  5. +----------------------------------------------------+
  6. | ("player100" :player{name: "Tim Duncan", age: 42}) |
  7. +----------------------------------------------------+

使用WHERE子句也可以实现相同的操作:

  1. nebula> MATCH (v:player) WHERE v.name == "Tim Duncan" RETURN v;
  2. +----------------------------------------------------+
  3. | v |
  4. +----------------------------------------------------+
  5. | ("player100" :player{name: "Tim Duncan", age: 42}) |
  6. +----------------------------------------------------+

openCypher兼容性:在openCypher 9中,=是相等运算符,在nGQL中,==是相等运算符,=是赋值运算符。

匹配点ID

您可以使用点ID去匹配点。id()函数可以检索点的ID。

  1. nebula> MATCH (v) WHERE id(v) == 'player101' RETURN v;
  2. +---------------------------------------------------+
  3. | v |
  4. +---------------------------------------------------+
  5. | (player101) player.name:Tony Parker,player.age:36 |
  6. +---------------------------------------------------+

要匹配多个点的ID,可以用WHERE id(v) IN [vid_list]

  1. nebula> MATCH (v:player { name: 'Tim Duncan' })--(v2) \
  2. WHERE id(v2) IN ["player101", "player102"] RETURN v2;
  3. +-----------------------------------------------------------+
  4. | v2 |
  5. +-----------------------------------------------------------+
  6. | ("player101" :player{name: "Tony Parker", age: 36}) |
  7. +-----------------------------------------------------------+
  8. | ("player102" :player{name: "LaMarcus Aldridge", age: 33}) |
  9. +-----------------------------------------------------------+
  10. | ("player101" :player{name: "Tony Parker", age: 36}) |
  11. +-----------------------------------------------------------+

匹配连接的点

您可以使用--符号表示两个方向的边,并匹配这些边连接的点。

说明:在nGQL 1.x中,--符号用于行内注释,在nGQL 2.x中,--符号表示出边或入边。

  1. nebula> MATCH (v:player{name:"Tim Duncan"})--(v2) \
  2. RETURN v2.name AS Name;
  3. +---------------------+
  4. | Name |
  5. +---------------------+
  6. | "Tony Parker" |
  7. +---------------------+
  8. | "LaMarcus Aldridge" |
  9. +---------------------+
  10. | "Marco Belinelli" |
  11. +---------------------+
  12. | "Danny Green" |
  13. +---------------------+
  14. | "Aron Baynes" |
  15. +---------------------+
  16. ...

您可以在--符号上增加<>符号指定边的方向。

  1. # -->表示边从v开始,指向v2。对于点v来说是出边,对于点v2来说是入边。
  2. nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2) \
  3. RETURN v2.name AS Name;
  4. +-----------------+
  5. | Name |
  6. +-----------------+
  7. | "Spurs" |
  8. +-----------------+
  9. | "Tony Parker" |
  10. +-----------------+
  11. | "Manu Ginobili" |
  12. +-----------------+

如果需要扩展模式,可以增加更多点和边。

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-->(v2)<--(v3) \
  2. RETURN v3.name AS Name;
  3. +---------------------+
  4. | Name |
  5. +---------------------+
  6. | "Tony Parker" |
  7. +---------------------+
  8. | "Tiago Splitter" |
  9. +---------------------+
  10. | "Dejounte Murray" |
  11. +---------------------+
  12. | "Tony Parker" |
  13. +---------------------+
  14. | "LaMarcus Aldridge" |
  15. +---------------------+
  16. ...

如果您不需要引用点,可以省略括号中表示点的变量。

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-->()<--(v3) \
  2. RETURN v3.name AS Name;
  3. +---------------------+
  4. | Name |
  5. +---------------------+
  6. | "Tony Parker" |
  7. +---------------------+
  8. | "LaMarcus Aldridge" |
  9. +---------------------+
  10. | "Rudy Gay" |
  11. +---------------------+
  12. | "Danny Green" |
  13. +---------------------+
  14. | "Kyle Anderson" |
  15. +---------------------+
  16. ...

匹配路径

连接起来的点和边构成了路径。您可以使用自定义变量命名路径。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-->(v2) \
  2. RETURN p;
  3. +-------------------------------------------+
  4. | p |
  5. +-------------------------------------------+
  6. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})> |
  7. +-------------------------------------------+
  8. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})> |
  9. +-------------------------------------------+
  10. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:serve@0 {end_year: 2016, start_year: 1997}]->("team204" :team{name: "Spurs"})> |
  11. +-------------------------------------------+

openCypher兼容性:在nGQL中,@符号表示边的rank,在openCypher中,没有rank概念。

匹配边

除了用----><--表示未命名的边之外,您还可以在方括号中使用自定义变量命名边。例如-[e]-

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-[e]-(v2) \
  2. RETURN e;
  3. +---------------------------------------------------------------------------+
  4. | e |
  5. +---------------------------------------------------------------------------+
  6. | [:follow "player101"->"player100" @0 {degree: 95}] |
  7. +---------------------------------------------------------------------------+
  8. | [:follow "player102"->"player100" @0 {degree: 75}] |
  9. +---------------------------------------------------------------------------+
  10. | [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
  11. +---------------------------------------------------------------------------+
  12. ...

匹配边类型和属性

和点一样,您可以用:<edge_type>表示模式中的边类型。例如-[e:serve]-

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-[e:serve]-(v2) \
  2. RETURN e;
  3. +---------------------------------------------------------------------------+
  4. | e |
  5. +---------------------------------------------------------------------------+
  6. | [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
  7. +---------------------------------------------------------------------------+

您可以用{<prop_name>: <prop_value>}表示模式中边类型的属性。例如[e:follow{likeness:95}]

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-[e:follow{degree:95}]->(v2) \
  2. RETURN e;
  3. +--------------------------------------------------------+
  4. | e |
  5. +--------------------------------------------------------+
  6. | [:follow "player100"->"player101" @0 {degree: 95}] |
  7. +--------------------------------------------------------+
  8. | [:follow "player100"->"player125" @0 {degree: 95}] |
  9. +--------------------------------------------------------+

匹配多个边类型

使用|可以匹配多个边类型。例如[e:follow|:serve]

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-[e:follow|:serve]->(v2) \
  2. RETURN e;
  3. +---------------------------------------------------------------------------+
  4. | e |
  5. +---------------------------------------------------------------------------+
  6. | [:follow "player100"->"player101" @0 {degree: 95}] |
  7. +---------------------------------------------------------------------------+
  8. | [:follow "player100"->"player125" @0 {degree: 95}] |
  9. +---------------------------------------------------------------------------+
  10. | [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
  11. +---------------------------------------------------------------------------+

匹配多条边

您可以扩展模式,匹配路径中的多条边。

  1. nebula> MATCH (v:player{name:"Tim Duncan"})-[]->(v2)<-[e:serve]-(v3) \
  2. RETURN v2, v3;
  3. +------------------------------------+-----------------------------------------------------------+
  4. | v2 | v3 |
  5. +------------------------------------+-----------------------------------------------------------+
  6. | ("player204" :team{name: "Spurs"}) | ("player101" :player{name: "Tony Parker", age: 36}) |
  7. +------------------------------------+-----------------------------------------------------------+
  8. | ("player204" :team{name: "Spurs"}) | ("player102" :player{name: "LaMarcus Aldridge", age: 33}) |
  9. +------------------------------------+-----------------------------------------------------------+
  10. | ("player204" :team{name: "Spurs"}) | ("player103" :player{age: 32, name: "Rudy Gay"}) |
  11. +------------------------------------+-----------------------------------------------------------+
  12. ...

匹配定长路径

您可以在模式中使用:<edge_type>*<hop>匹配定长路径。hop必须是一个非负整数。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*2]->(v2) \
  2. RETURN DISTINCT v2 AS Friends;
  3. +-----------------------------------------------------------+
  4. | Friends |
  5. +-----------------------------------------------------------+
  6. | ("player100" :player{name: "Tim Duncan", age: 42}) |
  7. +-----------------------------------------------------------+
  8. | ("player102" :player{name: "LaMarcus Aldridge", age: 33}) |
  9. +-----------------------------------------------------------+
  10. | ("player125" :player{name: "Manu Ginobili", age: 41}) |
  11. +-----------------------------------------------------------+

如果hop为0,模式会匹配路径上的起始点。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) -[*0]-> (v2) \
  2. RETURN v2;
  3. +----------------------------------------------------+
  4. | v2 |
  5. +----------------------------------------------------+
  6. | ("player100" :player{age: 42, name: "Tim Duncan"}) |
  7. +----------------------------------------------------+

匹配变长路径

您可以在模式中使用:<edge_type>*[minHop]..<maxHop>匹配变长路径。

参数说明
minHop可选项。表示路径的最小长度。minHop必须是一个非负整数,默认值为1。
maxHop必选项。表示路径的最大长度。maxHop必须是一个非负整数,没有默认值。

openCypher兼容性:在openCypher中,maxHop是可选项,默认为无穷大。当没有设置时,..可以省略。在nGQL中,maxHop是必选项,而且..不可以省略。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*1..3]->(v2) \
  2. RETURN v2 AS Friends;
  3. +-----------------------------------------------------------+
  4. | Friends |
  5. +-----------------------------------------------------------+
  6. | ("player100" :player{age: 42, name: "Tim Duncan"}) |
  7. +-----------------------------------------------------------+
  8. | ("player101" :player{age: 36, name: "Tony Parker"}) |
  9. +-----------------------------------------------------------+
  10. | ("player125" :player{age: 41, name: "Manu Ginobili"}) |
  11. +-----------------------------------------------------------+
  12. | ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
  13. +-----------------------------------------------------------+

您可以使用DISTINCT关键字聚合重复结果。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*1..3]->(v2:player) \
  2. RETURN DISTINCT v2 AS Friends, count(v2);
  3. +-----------------------------------------------------------+-----------+
  4. | Friends | COUNT(v2) |
  5. +-----------------------------------------------------------+-----------+
  6. | ("player125" :player{age: 41, name: "Manu Ginobili"}) | 3 |
  7. +-----------------------------------------------------------+-----------+
  8. | ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) | 1 |
  9. +-----------------------------------------------------------+-----------+
  10. | ("player100" :player{age: 42, name: "Tim Duncan"}) | 4 |
  11. +-----------------------------------------------------------+-----------+
  12. | ("player101" :player{age: 36, name: "Tony Parker"}) | 3 |
  13. +-----------------------------------------------------------+-----------+

如果minHop0,模式会匹配路径上的起始点。与上个示例相比,下面的示例设置minHop0,因为它是起始点,所以结果集中"Tim Duncan"比上个示例多计算一次。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow*0..3]->(v2:player) \
  2. RETURN DISTINCT v2 AS Friends, count(v2);
  3. +-----------------------------------------------------------+-----------+
  4. | Friends | COUNT(v2) |
  5. +-----------------------------------------------------------+-----------+
  6. | ("player125" :player{age: 41, name: "Manu Ginobili"}) | 3 |
  7. +-----------------------------------------------------------+-----------+
  8. | ("player101" :player{age: 36, name: "Tony Parker"}) | 3 |
  9. +-----------------------------------------------------------+-----------+
  10. | ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) | 1 |
  11. +-----------------------------------------------------------+-----------+
  12. | ("player100" :player{age: 42, name: "Tim Duncan"}) | 5 |
  13. +-----------------------------------------------------------+-----------+

匹配多个边类型的变长路径

您可以在变长或定长模式中指定多个边类型。hopminHopmaxHop对所有边类型都生效。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e:follow|serve*2]->(v2) \
  2. RETURN DISTINCT v2;
  3. +-----------------------------------------------------------+
  4. | v2 |
  5. +-----------------------------------------------------------+
  6. | ("player100" :player{name: "Tim Duncan", age: 42}) |
  7. +-----------------------------------------------------------+
  8. | ("player102" :player{name: "LaMarcus Aldridge", age: 33}) |
  9. +-----------------------------------------------------------+
  10. | ("player125" :player{name: "Manu Ginobili", age: 41}) |
  11. +-----------------------------------------------------------+
  12. | ("player204" :team{name: "Spurs"}) |
  13. +-----------------------------------------------------------+
  14. | ("player215" :team{name: "Hornets"}) |
  15. +-----------------------------------------------------------+

常用检索操作

检索点或边的信息

使用RETURN {<vertex_name> | <edge_name>}检索点或边的所有信息。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN v;
  3. +----------------------------------------------------+
  4. | v |
  5. +----------------------------------------------------+
  6. | ("player100" :player{name: "Tim Duncan", age: 42}) |
  7. +----------------------------------------------------+
  8. nebula> MATCH (v:player{name:"Tim Duncan"})-[e]->(v2) \
  9. RETURN e;
  10. +---------------------------------------------------------------------------+
  11. | e |
  12. +---------------------------------------------------------------------------+
  13. | [:follow "player100"->"player101" @0 {degree: 95}] |
  14. +---------------------------------------------------------------------------+
  15. | [:follow "player100"->"player125" @0 {degree: 95}] |
  16. +---------------------------------------------------------------------------+
  17. | [:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}] |
  18. +---------------------------------------------------------------------------+

检索点ID

使用id()函数检索点ID。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN id(v);
  3. +-------------+
  4. | id(v) |
  5. +-------------+
  6. | "player100" |
  7. +-------------+

检索标签

使用labels()函数检索点上的标签列表。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN labels(v);
  3. +------------+
  4. | labels(v) |
  5. +------------+
  6. | ["player"] |
  7. +------------+

检索列表labels(v)中的第N个元素,可以使用labels(v)[n-1]。例如下面示例使用labels(v)[0]检索第一个元素。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN labels(v)[0];
  3. +--------------+
  4. | labels(v)[0] |
  5. +--------------+
  6. | "player" |
  7. +--------------+

检索点或边的单个属性

使用RETURN {<vertex_name> | <edge_name>}.<property>检索单个属性。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN v.age;
  3. +-------+
  4. | v.age |
  5. +-------+
  6. | 42 |
  7. +-------+

使用AS设置属性的别名。

  1. nebula> MATCH (v:player{name:"Tim Duncan"}) \
  2. RETURN v.age AS Age;
  3. +-----+
  4. | Age |
  5. +-----+
  6. | 42 |
  7. +-----+

检索点或边的所有属性

使用properties()函数检索点或边的所有属性。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
  2. RETURN properties(v2);
  3. +------------------------------------+
  4. | properties(v2) |
  5. +------------------------------------+
  6. | {"name":"Spurs"} |
  7. +------------------------------------+
  8. | {"name":"Tony Parker", "age":36} |
  9. +------------------------------------+
  10. | {"age":41, "name":"Manu Ginobili"} |
  11. +------------------------------------+

检索边类型

使用type()函数检索匹配的边类型。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[e]->() \
  2. RETURN DISTINCT type(e);
  3. +----------+
  4. | type(e) |
  5. +----------+
  6. | "follow" |
  7. +----------+
  8. | "serve" |
  9. +----------+

检索路径

使用RETURN <path_name>检索匹配路径的所有信息。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*3]->() \
  2. RETURN p;
  3. +-------------------------------------------------------------------------------------------------+
  4. | p |
  5. +-------------------------------------------------------------------------------------------------+
  6. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:serve@0 {end_year: 2019, start_year: 2015}]->("team204" :team{name: "Spurs"})> |
  7. +-------------------------------------------------------------------------------------------------+
  8. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:serve@0 {end_year: 2015, start_year: 2006}]->("team203" :team{name: "Trail Blazers"})> |
  9. +-------------------------------------------------------------------------------------------------+
  10. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})-[:follow@0 {degree: 75}]->("player101" :player{age: 36, name: "Tony Parker"})> |
  11. +-------------------------------------------------------------------------------------------------+
  12. ...

检索路径中的点

使用nodes()函数检索路径中的所有点。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
  2. RETURN nodes(p);
  3. +---------------------------------------------------------------------------------------------------------------------+
  4. | nodes(p) |
  5. +---------------------------------------------------------------------------------------------------------------------+
  6. | [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player204" :team{name: "Spurs"})] |
  7. +---------------------------------------------------------------------------------------------------------------------+
  8. | [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player101" :player{name: "Tony Parker", age: 36})] |
  9. +---------------------------------------------------------------------------------------------------------------------+
  10. | [("player100" :star{} :player{age: 42, name: "Tim Duncan"}), ("player125" :player{name: "Manu Ginobili", age: 41})] |
  11. +---------------------------------------------------------------------------------------------------------------------+

检索路径中的边

使用relationships()函数检索路径中的所有边。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[]->(v2) \
  2. RETURN relationships(p);
  3. +-----------------------------------------------------------------------------+
  4. | relationships(p) |
  5. +-----------------------------------------------------------------------------+
  6. | [[:follow "player100"->"player101" @0 {degree: 95}]] |
  7. +-----------------------------------------------------------------------------+
  8. | [[:follow "player100"->"player125" @0 {degree: 95}]] |
  9. +-----------------------------------------------------------------------------+
  10. | [[:serve "player100"->"team204" @0 {end_year: 2016, start_year: 1997}]] |
  11. +-----------------------------------------------------------------------------+

检索路径长度

使用length()函数检索路径的长度。

  1. nebula> MATCH p=(v:player{name:"Tim Duncan"})-[*..2]->(v2) \
  2. RETURN p AS Paths, length(p) AS Length;
  3. +----------------------------------------------------------------------+--------+
  4. | Paths | Length |
  5. +----------------------------------------------------------------------+--------+
  6. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})-[:serve@0 {end_year: 2018, start_year: 2002}]->("team204" :team{name: "Spurs"})> | 2 |
  7. +----------------------------------------------------------------------+--------+
  8. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})-[:follow@0 {degree: 90}]->("player100" :player{age: 42, name: "Tim Duncan"})> | 2 |
  9. +----------------------------------------------------------------------+--------+
  10. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2019, start_year: 2018}]->("team215" :team{name: "Hornets"})> | 2 |
  11. +----------------------------------------------------------------------+--------+
  12. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("team204" :team{name: "Spurs"})> | 2 |
  13. +----------------------------------------------------------------------+--------+
  14. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})> | 2 |
  15. +----------------------------------------------------------------------+--------+
  16. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})> | 2 |
  17. +----------------------------------------------------------------------+--------+
  18. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 95}]->("player100" :player{age: 42, name: "Tim Duncan"})> | 2 |
  19. +----------------------------------------------------------------------+--------+
  20. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:serve@0 {end_year: 2016, start_year: 1997}]->("team204" :team{name: "Spurs"})> | 1 |
  21. +----------------------------------------------------------------------+--------+
  22. | <("player100" :player{age: 42, name: "Tim Duncan"})-[:follow@0 {degree: 95}]->("player125" :player{age: 41, name: "Manu Ginobili"})> | 1 |
  23. +----------------------------------------------------------------------+--------+