关系是实体之间的连接。
一、建模关系
连接是用例中的动词:
- What ingredients areusedin a recipe?
- Who ismarriedto this person?
乍一看,连接很简单,但它们的微观和宏观设计可以说是图形性能中最关键的因素。使用“连接是动词”是一个很好的入门速记,但还有其他重要的注意事项,您将在本文后面学习。
命名关系
为图中的关系选择好的名称(类型)很重要。关系类型必须是对涉众和开发人员都很直观的类型。关系类型不能与实体名称混淆。
因此,在我们的示例用例中,我们可以定义这些关系类型:
- USES
- MARRIED
请注意,我们在关系的名称中使用了所有大写字母/下划线字符的Neo4j最佳实践。
关系方向
在Neo4j中创建关系时,必须显式指定方向,或者按照指定模式中从左到右的方向推断方向。但是,在运行时,在查询过程中,通常不需要方向。
在上面显示的示例用例中,必须创建USES关系才能从Recipe节点转到Ingredient节点。
由于这种类型的关系是对称的,因此可以在任一节点中创建MARRIED关系。
目标结果示意
这里,我们将实体(Person, Residence)表示为网络或链接节点,而不是单个节点。
这是一个极端例子,几乎可以肯定,对于任何实际解决方案来说,这都是过分的,但一定数量的扇出可能非常有用。
例如,将姓氏拆分到单独的节点有助于回答“谁姓Scott?”。同样,将城市作为单独的节点有助于解决“谁与帕特里克·斯科特住在同一个城市?”。
扇出的主要风险是它可能导致非常密集的节点或超级节点。这些节点具有成千上万的传入或传出关系,超级节点需要小心处理。
电影图表中的关系
现在,让我们来看下电影示例中的情形,来确定这些用例的关系:
- What peopleactedin a movie?
- What persondirecteda movie?
- What movies did a personactin?
鉴于这些用例,我们将这些关系命名为:
- ACTED_IN
- DIRECTED
此外,这两种关系类型都从Person节点开始,到Movie节点结束。
以下是支持的图形数据模型:
下面是支持此图数据模型的实例模型:
汤姆·汉克斯演了两部电影。梅格·瑞安和杰克·尼科尔森分别出演了一部电影。丹尼·德维托(Danny DeVito)曾出演并执导过同一部电影。探索与此实例模型的关系,我们可以看到电影《阿波罗13号》在图中只有一个演员,但其他两部电影各有两个演员。
关系的属性
关系的属性用于丰富两个节点的关联方式。当您为关系定义属性时,这是因为您的用例询问了一个关于两个节点如何相关的特定问题,而不仅仅是它们是相关的。
例如,我们在Neo4j基础课程中看到,可以将属性添加到关系中以进一步描述它。
这里我们看到,我们有一个关于婚姻关系的日期属性,以进一步描述迈克尔和莎拉之间的关系。此外,我们在WORKS\u AT关系中有一个角色属性,用于描述Michael在Graph股份有限公司工作时所扮演的角色。
这些属性特定于两个节点之间的关系。
电影图中的关系属性
就像您分析命名标签、关系类型和节点属性的用例一样,您也可以使用这些用例来生成关系的属性。
以下是一个用例:
- 一个人在电影中扮演什么角色?
此用例的运行时操作包括:
- 检索此人的姓名。
- 在与电影的关系中遵循ACTED_IN。
- 按电影标题过滤电影。
- 从两个节点之间的ACTED_IN关系中返回角色。
我们知道,对于这个用例,关系中的特定ACTED_IN的角色是必要的。因此,我们将role属性添加到此关系中。以下是数据模型:
下面是您将要创建的实例模型:
注意到:此处的每个ACTED_IN关系都具有不同的role属性值。
二、创建初始关系
以下是您将要创建的实例模型:
此处的每个ACTED_IN关系都具有不同的role属性值。
运行此Cypher脚本将ACTED_IN和DIRECTED关系添加到图:
MATCH (apollo:Movie {title: 'Apollo 13'})
MATCH (tom:Person {name: 'Tom Hanks'})
MATCH (meg:Person {name: 'Meg Ryan'})
MATCH (danny:Person {name: 'Danny DeVito'})
MATCH (sleep:Movie {title: 'Sleepless in Seattle'})
MATCH (hoffa:Movie {title: 'Hoffa'})
MATCH (jack:Person {name: 'Jack Nicholson'})
// create the relationships between nodes
MERGE (tom)-[:ACTED_IN {role: 'Jim Lovell'}]->(apollo)
MERGE (tom)-[:ACTED_IN {role: 'Sam Baldwin'}]->(sleep)
MERGE (meg)-[:ACTED_IN {role: 'Annie Reed'}]->(sleep)
MERGE (danny)-[:ACTED_IN {role: 'Bobby Ciaro'}]->(hoffa)
MERGE (danny)-[:DIRECTED]->(hoffa)
MERGE (jack)-[:ACTED_IN {role: 'Jimmy Hoffa'}]->(hoffa)
您可以验证是否已使用以下代码创建了关系:
MATCH (n) RETURN n
图中应总共有6个关系。
三、标识新关系
现在我们有了一个如下的新用例,所以需要重构模型:
Use case #9: What users gave a movie a rating of 5?
我们已经确定了用例中的Person和Movie节点以及ACTED\u和DIRECTED关系:
- What peopleactedin a movie?
- What persondirecteda movie?
- What movies did a personactin?
我们还有一个额外的用例,我们必须对其进行建模,以询问对电影进行评级的用户的问题。我们定义了用户标签,以表示审查或评价电影的用户。
四、创建更多关系
我们希望在User节点和Movie节点之间添加一些关系,以便测试我们的模型。在此挑战中,您将创建包含rating属性的RATED关系。
在此挑战中,您将创建包含rating属性的RATED关系。
上面的Cypher脚本创建了Sandy Jones和Apollo 13之间的关系,评分为5。你可以接着下面的代码继续添加其他MERGE脚本代码,以根据下表创建其余4个关系:
注意:第一次MERGE脚本已经为您编写完毕了(见上述脚本)。
上述代码中,我们使用“MATCH”查找User 和Movie 节点,然后使用“MERGE”创建两个节点之间的关系。请记住,创建关系时必须指定或推断(从左到右)方向。您应该在图中总共创建5个分级关系,每个关系都有一个属性rating。
引用
https://graphacademy.neo4j.com/courses/modeling-fundamentals/1-getting-started/2-the-domain/