精华 Neo4j官方教程:第9节,实践中的模式
发布于 14 天前 作者 pangguoming 117 次浏览 来自 分享

教程目录 引自:https://neo4j.com/docs/getting-started/cypher-intro/patterns-in-practice/

实践中的模式

创建和返回数据

让我们首先看看允许您创建数据的子句。

要添加数据,您只需使用您已经知道的模式。通过提供模式,您可以指定哪些图结构、标签和属性要成为图的一部分。

显然,最简单的子句称为 CREATE。它创建您指定的模式。

对于您到目前为止所看到的模式,这可能如下所示:

CREATE (:Movie {title: 'The Matrix', released: 1997})

如果您运行此语句,Cypher® 将返回更改的数量:在本例中,添加一个节点、一个标签和两个属性。

Created Nodes: 1
Added Labels: 1
Set Properties: 2
Rows: 0

由于您从一个空数据库开始,因此您现在有一个数据库,其中包含一个节点: image cypher intro patterns in practice01 arr

如果您还想返回创建的数据,您可以添加一个 RETURN 子句,该子句引用您已分配给模式元素的变量。 Cypher 中的 RETURN 关键字指定您可能希望从 Cypher 查询返回的值或结果。 您可以告诉 Cypher 返回节点、关系、节点和关系属性或查询结果中的模式。 执行写入过程时不需要 RETURN,但读取时需要。 当使用 RETURN 时,前面讨论的节点和关系变量变得很重要。

CREATE (p:Person {name: 'Keanu Reeves', born: 1964})
RETURN p

这是返回的内容:

Created Nodes: 1
Added Labels: 1
Set Properties: 2
Rows: 1

+----------------------------------------------+
| p                                            |
+----------------------------------------------+
| (:Person {name: 'Keanu Reeves', born: 1964}) |
+----------------------------------------------+

如果要创建多个元素,可以用逗号分隔元素或使用多个 CREATE 语句。

当然,您还可以创建更复杂的结构,例如包含有关角色的信息的 ACTED_IN 关系,或导演的 DIRECTED 关系。

CREATE (a:Person {name: 'Tom Hanks', born: 1956})-[r:ACTED_IN {roles: ['Forrest']}]->(m:Movie {title: 'Forrest Gump', released: 1994})
CREATE (d:Person {name: 'Robert Zemeckis', born: 1951})-[:DIRECTED]->(m)
RETURN a, d, r, m

这是更新后的图的一部分: image cypher intro patterns in practice02 arr

在大多数情况下,您希望将新数据添加到现有结构。这需要知道如何在图数据中查找现有模式,这将在下一节中介绍。

匹配模式

匹配模式是 MATCH 语句的任务。您将到目前为止使用的相同类型的模式传递给 MATCH,以描述您要查找的内容。它类似于按示例查询,只是您的示例还包括结构。要返回节点、关系、属性或模式,您需要在 MATCH 子句中为要返回的数据指定变量。

MATCH 语句搜索您指定的模式,并为每个成功的模式匹配返回一行。

要查找您到目前为止创建的数据,您可以开始查找所有带有 Movie 标签的节点。

MATCH (m:Movie)
RETURN m

结果如下: image

cypher intro patterns in practice03 arr

这应该显示《黑客帝国》和《阿甘正传》。

您还可以查找特定的人,例如基努·里维斯。

MATCH (p:Person {name: 'Keanu Reeves'})
RETURN p

此查询返回匹配的节点: image cypher intro patterns in practice04 arr

请注意,您只提供足够的信息来查找节点,并非所有属性都是必需的。在大多数情况下,您都有关键属性,例如 SSN、ISBN、电子邮件、登录名、地理位置或产品代码来查找。

您还可以找到更有趣的连接,例如,汤姆·汉克斯出演的电影的标题和他扮演的角色。

MATCH (p:Person {name: 'Tom Hanks'})-[r:ACTED_IN]->(m:Movie)
RETURN m.title, r.roles
Rows: 1

+------------------------------+
| m.title        | r.roles     |
+------------------------------+
| 'Forrest Gump' | ['Forrest'] |
+------------------------------+

在本例中,您只返回了您感兴趣的节点和关系的属性。您可以通过点表示法 identifier.property 在任何地方访问它们。

当然,这只列出了汤姆·汉克斯在《阿甘正传》中扮演的 Forrest 角色,因为这就是您添加的所有数据。

现在您已经知道足够多的知识来将新节点添加到现有节点,并且可以将 MATCHCREATE 组合起来以将结构附加到图中。

Cypher 示例

让我们看一些使用 MATCHRETURN 关键字的示例。每个后续示例都比前一个示例更复杂。最后两个示例首先解释了我们试图实现的目标。如果您单击每个 Cypher 代码段下方的“运行查询”按钮,您可以在图或表的格式中查看结果。

示例 1:查找图中带有标签 Person 的节点。请注意,如果要检索 RETURN 子句中的节点,则必须为 Person 节点使用一个变量,例如 p

MATCH (p:Person)
RETURN p
LIMIT 1

示例 2:查找图中名称为“Tom Hanks”的 Person 节点。请记住,您可以随意命名您的变量,只要您稍后引用相同的名称即可。

MATCH (tom:Person {name: 'Tom Hanks'})
RETURN tom

示例 3:查找汤姆·汉克斯导演的电影。

说明:首先,您应该找到汤姆·汉克斯的 Person 节点,然后找到他连接到的 Movie 节点。为此,您必须从汤姆·汉克斯的 Person 节点到 Movie 节点遵循 DIRECTED 关系。您还指定了 Movie 的标签,以便查询仅查看带有该标签的节点。由于您只关心在此查询中返回电影,因此您需要为该节点提供一个变量(movie),但不需要为 Person 节点或 DIRECTED 关系提供变量。

MATCH (:Person {name: 'Tom Hanks'})-[:DIRECTED]->(movie:Movie)
RETURN movie

示例 4:查找汤姆·汉克斯导演的电影,但这次只返回电影的标题。

说明:此查询与上一个查询类似。示例 3 返回了整个 Movie 节点及其所有属性。对于此示例,您仍然需要找到汤姆的电影,但现在您只关心它们的标题。您应该使用语法 variable.property 访问节点的 title 属性以返回名称值。

MATCH (:Person {name: 'Tom Hanks'})-[:DIRECTED]->(movie:Movie)
RETURN movie.title

别名返回值

并非所有属性都像上面示例中的 movie.title 那样简单。由于属性长度、多字描述、开发人员术语和其他快捷方式,某些属性的名称很差。这些命名约定可能难以阅读,尤其是在报告和其他面向用户的界面上。

命名不佳的属性

// 命名不佳的属性
MATCH (tom:Person {name:'Tom Hanks'})-[rel:DIRECTED]-(movie:Movie)
RETURN tom.name, tom.born, movie.title, movie.released

就像 SQL 一样,您可以使用 AS 关键字重命名返回结果,并使用更清晰的名称为属性设置别名。

使用别名获得更清晰的结果

// 使用别名获得更清晰的打印结果
MATCH (tom:Person {name:'Tom Hanks'})-[rel:DIRECTED]-(movie:Movie)
RETURN tom.name AS name, tom.born AS `Year Born`, movie.title AS title, movie.released AS `Year Released`

您可以通过在别名前后使用反引号字符来指定包含空格的返回别名(movie.released AS Year Released)。如果您没有包含空格的别名,则无需使用反引号。

附加结构

要使用新信息扩展图,首先要匹配现有的连接点,然后使用关系将新创建的节点附加到它们。像这样可以为汤姆·汉克斯添加一部新电影《云图》:

MATCH (p:Person {name: 'Tom Hanks'})
CREATE (m:Movie {title: 'Cloud Atlas', released: 2012})
CREATE (p)-[r:ACTED_IN {roles: ['Zachry']}]->(m)
RETURN p, r, m

这是数据库中的结构: image cypher intro patterns in practice05 arr

重要的是要记住,您可以为节点和关系分配变量,并在以后使用它们,无论它们是创建的还是匹配的。

可以在单个 CREATE 子句中附加节点和关系。但是,为了提高可读性,将它们分开是有帮助的。

MATCHCREATE 组合的一个棘手方面是,每个匹配的模式都会得到一行。这会导致后续的 CREATE 语句为每一行执行一次。在许多情况下,这正是您想要的。如果不是有意的,请将 CREATE 语句移动到 MATCH 之前,或者使用稍后讨论的方法更改查询的基数,或者使用下一个子句的获取或创建语义:MERGE

完成模式

每当您从外部系统获取数据或不确定某些信息是否已存在于图中时,您都希望能够表达可重复(幂等)的更新操作。在 Cypher 中,MERGE 子句具有此功能。它的作用类似于 MATCHCREATE 的组合,它在创建数据之前检查数据是否存在。使用 MERGE,您可以定义要查找或创建的模式。通常,与 MATCH 一样,您只想在核心模式中包含要查找的关键属性。MERGE 允许您提供要在 ON CREATE 上设置的其他属性。

如果您不知道您的图是否已经包含《云图》,您可以再次合并它。

MERGE (m:Movie {title: 'Cloud Atlas'})
ON CREATE SET m.released = 2012
RETURN m
Created Nodes: 1
Added Labels: 1
Set Properties: 2
Rows: 1

+-------------------------------------------------+
| m                                               |
+-------------------------------------------------+
| (:Movie {title: 'Cloud Atlas', released: 2012}) |
+-------------------------------------------------+

在这两种情况下,您都会得到一个结果:要么是图中已经存在的数据(可能不止一行),要么是一个新创建的 Movie 节点。

没有任何先前分配变量的 MERGE 子句要么匹配完整模式,要么创建完整模式。它永远不会产生模式中匹配和创建的部分混合。要实现部分匹配/创建,请确保对不应受影响的部分使用已定义的变量。

因此,最重要的是,MERGE 确保您不能创建重复的信息或结构,但它需要首先检查现有匹配项的成本。尤其是在大型图上,扫描一组带有标签的节点以查找特定属性可能代价高昂。您可以通过创建支持索引或约束来缓解这种情况,这将在后面的章节中讨论。但这仍然不是免费的,因此,只要您确定不会创建重复数据,请使用 CREATE 而不是 MERGE

MERGE 还可以断言仅创建一次关系。为此,您必须从先前的模式匹配中传入两个节点。

MATCH (m:Movie {title: 'Cloud Atlas'})
MATCH (p:Person {name: 'Tom Hanks'})
MERGE (p)-[r:ACTED_IN]->(m)
ON CREATE SET r.roles =['Zachry']
RETURN p, r, m

image cypher intro patterns in practice06 arr

如果关系的方向是任意的,您可以省略箭头。MERGE 检查任一方向的关系,如果没有匹配的关系,则创建一个新的有向关系。

如果您选择仅从前面的子句中传入一个节点,则 MERGE 提供了一个有趣的功能。它仅在给定模式的提供的节点的直接邻域内匹配,如果未找到该模式,则创建它。这对于创建树结构非常有用。

CREATE (y:Year {year: 2014})
MERGE (y)<-[:IN_YEAR]-(m10:Month {month: 10})
MERGE (y)<-[:IN_YEAR]-(m11:Month {month: 11})
RETURN y, m10, m11

这是创建的图结构: image cypher intro patterns in practice07 arr

这里没有对两个 Month 节点进行全局搜索;仅在 2014 Year 节点的上下文中搜索它们。

代码挑战

现在了解了基础知识,请使用下面的部分构建一个 Cypher 语句,以查找汤姆·汉克斯 DIRECTED 的每个 Movie 的标题和发行年份。单击这些部分以按顺序添加它们,完成后,单击“运行查询”以查看您是否正确。您可以单击代码块内的任何查询部分以将其删除。

从下面的选项中选择以完成查询:

{name:})-[:MovieRETURNPerson"Tom Hanks")m.title, m.released]->(m:DIRECTED(p:MATCH
回到顶部