Neo4j图数据建模基础|消除重复数据
  iwbGD3gmtxyT 2023年11月02日 100 0

一、消除重复数据

重复数据

应该注意避免在图形中重复数据。当一些数据库需要某种形式的非规范化来提高一组查询的速度时,图数据库并不总是这样。重复数据消除为您提供了额外的好处,允许您通过节点进行查询,例如,查找购买了特定产品的其他客户,或者根据其他用户的评分查找类似的电影。

此外,复制图中的数据会增加图的大小以及查询可能需要检索的数据量。

新用例

我们有一个必须说明的新用例,如下所示。

用例#11:给定某种特定语言,则存在哪些相应的电影?

我们当前的实例模型如下所示:

Neo4j图数据建模基础|消除重复数据_用例

如您所见,我们在数据模型中没有考虑语言,因此我们必须添加这类数据。

重复数据示例

假设我们向名为languages的图中的每个电影节点添加一个属性,该属性表示电影可用的语言。

下面是实例模型的外观:

Neo4j图数据建模基础|消除重复数据_数据_02

在这里,我们看到所有Movie影节点的语言列表中都有英语。这是重复的数据,对于一个按比例缩放的数据库来说,将意味着存在大量的重复。

添加语言数据

在上面,我们了解到复制图中的数据可能会付出很昂贵的代价。为了说明数据的重复,您将向实例模型中的每个电影节点添加一个languages属性。

执行如下的Cypher将语言属性添加到图形的电影节点上:

MATCH (apollo:Movie {title: 'Apollo 13', tmdbId: 568, released: '1995-06-30', imdbRating: 7.6, genres: ['Drama', 'Adventure', 'IMAX']})
MATCH (sleep:Movie {title: 'Sleepless in Seattle', tmdbId: 858, released: '1993-06-25', imdbRating: 6.8, genres: ['Comedy', 'Drama', 'Romance']})
MATCH (hoffa:Movie {title: 'Hoffa', tmdbId: 10410, released: '1992-12-25', imdbRating: 6.6, genres: ['Crime', 'Drama']})
MATCH (casino:Movie {title: 'Casino', tmdbId: 524, released: '1995-11-22', imdbRating: 8.2, genres: ['Drama','Crime']})
SET apollo.languages = ['English']
SET sleep.languages = ['English']
SET hoffa.languages = ['English', 'Italian', 'Latin']
SET casino.languages = ['English']

下面是相应的实例模型:

Neo4j图数据建模基础|消除重复数据_用例_03

查询语言

下面是一个支持我们新用例的查询:

用例#11:以特定语言提供哪些电影?

通过此查询,我们可以找到所有意大利语电影。

执行下面的查询并回答下一个问题。

MATCH (m:Movie)
WHERE 'Italian' IN m.languages
RETURN m.title

哪部电影以意大利语对话为特色?

二、重构重复数据

查询重复数据

下面是我们当前的实例模型,其中每个电影节点都有一个languages属性:

Neo4j图数据建模基础|消除重复数据_用例_04

对于我们最新的用例:

用例#11:以特定语言提供哪些电影?

此查询查找所有意大利语电影:

MATCH (m:Movie)
WHERE 'Italian' IN m.languages
RETURN m.title

此查询所做的是检索所有电影节点,然后测试languages属性是否包含意大利语。数据模型有两个问题,尤其是当图表缩放时:

  • 该语言的名称在许多电影节点中重复。
  • 为了执行查询,必须检索所有电影节点。

这里的一个解决方案是将属性建模为节点。

将属性重构为节点

以下是我们用于重构的步骤:

  1. 我们获取每个电影节点的属性值并创建一个语言节点。
  2. 然后,我们在电影节点和语言节点之间创建IN_LANGUAGE关系。
  3. 最后,我们从Movie节点中删除languages属性。

这是重构图形以将属性值转换为节点的代码:

MATCH (m:Movie)
UNWIND m.languages AS language
WITH language, collect(m) AS movies
MERGE (l:Language {name:language})
WITH l, movies
UNWIND movies AS m
WITH l,m
MERGE (m)-[:IN_LANGUAGE]->(l);
MATCH (m:Movie)
SET m.languages = null

此代码遍历所有电影节点,并为找到的每种语言创建一个语言节点,然后使用IN\u语言关系创建电影节点和语言节点之间的关系。它使用Cypher UNWIND子句将languages属性列表的每个元素分隔为一个单独的行值,该行值稍后将在查询中处理。

重构后的实例模型是这样的:

Neo4j图数据建模基础|消除重复数据_用例_05


只有一个节点的语言值为English,我们将从所有电影节点中删除languages属性。这消除了图形中的大量重复。

添加语言节点

实例模型将被重构为:

Neo4j图数据建模基础|消除重复数据_用例_06


创建语言节点

执行以下代码重构图形,将语言属性值转换为语言节点:

MATCH (m:Movie)
UNWIND m.languages AS language
WITH language, collect(m) AS movies
MERGE (l:Language {name:language})
WITH l, movies
UNWIND movies AS m
WITH l,m
MERGE (m)-[:IN_LANGUAGE]->(l);
MATCH (m:Movie)
SET m.languages = null

修改Cypher查询

这是我们的用例在重构之前的Cypher。

MATCH (m:Movie)
WHERE 'Italian' IN m.languages
RETURN m.title

现在可以修改此查询,以使用新创建的语言节点。

MATCH (m:Movie)-[:IN_LANGUAGE]-(l:Language)
WHERE l.name = 'Italian'
RETURN m.title

这是处理语言的唯一用例,因此我们不需要在重构后重新测试所有查询。

添加流派节点

在上面重构中,通过在languages属性中获取数据并创建与电影相关的语言节点,消除了重复。

此挑战包括三个步骤:

  • 修改并运行查询,以使用电影节点的genres属性中的数据,并使用IN_GENRE关系创建Genre节点,以将Movie节点连接到Genre节点。
  • 从电影节点中删除genres属性。
  • 重写用例的查询:演员在哪些戏剧电影中扮演角色?

将此查询复制到Neo4j桌面应用查询窗格,重写它,然后测试此Cypher查询,以与TomHanks一起测试此用例。

MATCH (p:Actor)-[:ACTED_IN]-(m:Movie)
WHERE p.name = 'Tom Hanks' AND
'Drama' IN m.genres
RETURN m.title AS Movie

应该返回电影:Apollo 13 和 Sleepless in Seattle。

执行查询

使用查询窗口展开每个电影的Genre属性,然后创建新的节点和关系。

完成此操作后,单击“Check Database”以验证图是否已正确重构。

三、消除节点中的复杂数据

由于节点用于存储有关特定实体的数据,因此,可能已经对生产节点进行了初始建模,以包含生产公司地址的详细信息。

Neo4j图数据建模基础|消除重复数据_用例_07

由于以下几个原因,在这样的节点中存储复杂数据可能没有好处:

  • 重复数据。许多节点可能在特定位置都会拥有生产公司,并且这样的数据在许多节点中都会重复。
  • 与节点中的信息相关的查询要求能够检索所有节点。

重构复杂数据

如果节点中存在大量重复数据,或者如果不需要检索所有节点来获取复杂数据,那么用例的关键问题会表现得更好,那么,可以考虑重构图,如下图所示。

Neo4j图数据建模基础|消除重复数据_用例_08

在这种重构中,如果有查询需要按状态过滤生产公司,那么根据状态进行查询会更快。根据State.name进行查询,而不是计算Production节点的所有状态属性。

如何进行图重构以处理复杂数据,这将取决于图缩放时查询的性能。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
iwbGD3gmtxyT