更新图数据

本教程展示了如何通过更改、删除和添加节点、关系及属性来更新图中的信息。它还介绍了如何避免重复数据。

创建数据集

创建免费的 Aura 实例 后,点击“Connect”(连接)按钮并选择“Query”(查询)。在 Cypher® 编辑器中,复制并粘贴以下 Cypher 代码并执行查询

CREATE (diana:Person {name: "Diana"})
CREATE (melissa:Person {name: "Melissa", twitter: "@melissa"})
CREATE (dan:Person {name: "Dan", twitter: "@dan", yearsExperience: 6})
CREATE (sally:Person {name: "Sally", yearsExperience: 4})
CREATE (john:Person {name: "John", yearsExperience: 5})
CREATE (jennifer:Person {name: "Jennifer", twitter: "@jennifer", yearsExperience: 5})
CREATE (joe:Person {name: "Joe"})
CREATE (mark:Person {name: "Mark", twitter: "@mark"})
CREATE (ann:Person {name: "Ann"})
CREATE (xyz:Company {name: "XYZ"})
CREATE (x:Company {name: "Company X"})
CREATE (a:Company {name: "Company A"})
CREATE (Neo4j:Company {name: "Neo4j"})
CREATE (abc:Company {name: "ABC"})
CREATE (query:Technology {type: "Query Languages"})
CREATE (etl:Technology {type: "Data ETL"})
CREATE (integrations:Technology {type: "Integrations"})
CREATE (graphs:Technology {type: "Graphs"})
CREATE (dev:Technology {type: "Application Development"})
CREATE (java:Technology {type: "Java"})
CREATE (diana)-[:LIKES]->(query)
CREATE (melissa)-[:LIKES]->(query)
CREATE (dan)-[:LIKES]->(etl)<-[:LIKES]-(melissa)
CREATE (xyz)<-[:WORKS_FOR]-(sally)-[:LIKES]->(integrations)<-[:LIKES]-(dan)
CREATE (sally)<-[:IS_FRIENDS_WITH]-(john)-[:LIKES]->(java)
CREATE (john)<-[:IS_FRIENDS_WITH]-(jennifer)-[:LIKES]->(java)
CREATE (john)-[:WORKS_FOR]->(xyz)
CREATE (sally)<-[:IS_FRIENDS_WITH]-(jennifer)-[:IS_FRIENDS_WITH]->(melissa)
CREATE (joe)-[:LIKES]->(query)
CREATE (x)<-[:WORKS_FOR]-(diana)<-[:IS_FRIENDS_WITH]-(joe)-[:IS_FRIENDS_WITH]->(mark)-[:LIKES]->(graphs)<-[:LIKES]-(jennifer)-[:WORKS_FOR]->(Neo4j)
CREATE (ann)<-[:IS_FRIENDS_WITH]-(jennifer)-[:IS_FRIENDS_WITH]->(mark)
CREATE (john)-[:LIKES]->(dev)<-[:LIKES]-(ann)-[:IS_FRIENDS_WITH]->(dan)-[:WORKS_FOR]->(abc)
CREATE (ann)-[:WORKS_FOR]->(abc)
CREATE (a)<-[:WORKS_FOR]-(melissa)-[:LIKES]->(graphs)<-[:LIKES]-(diana)

现在你应该拥有一个包含 20 个节点、31 个关系、28 个属性和 20 个标签的图。

All nodes added to the graph

为节点添加属性

如果你想为名叫 Jennifer 的人添加生日,可以使用以下查询将此信息作为 属性 添加进去

MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-01')
RETURN p

此查询执行以下操作

  1. 使用 MATCH 子句找到 Jennifer 的节点。

  2. 使用 SET 创建新属性 birthday(语法为 variable.property)并设置其值。

  3. 使用 RETURN 返回 Jennifer 的节点,以便确认信息已正确更新。

这是表格形式的查询结果

p

(:Person {twitter: "@jennifer", birthdate: 1980-01-01, name: "Jennifer", yearsExperience: 5})

行:1

更新属性

要更改 Jennifer 的生日,你可以使用上一个示例中相同的查询再次找到 Jennifer 的节点,并通过 SET 子句设置不同的日期来修改属性值

MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-02')
RETURN p

这是表格形式的查询结果

p

(:Person {twitter: "@jennifer", birthdate: 1980-01-02, name: "Jennifer", yearsExperience: 5})

行:1

删除属性

要删除属性,可以使用 REMOVE 子句,或者将其值设置为 null。Neo4j 不会存储没有值的属性,因此这样做会从节点中移除该属性。

使用 REMOVE 子句
MATCH (n:Person {name: 'Jennifer'})
REMOVE n.birthdate
使用 SET 子句
MATCH (n:Person {name: 'Jennifer'})
SET n.birthdate = null

使用上述两种方式,结果均为“Set 1 property”(设置 1 个属性),当你使用 MATCH 查看时,会发现结果显示属性值为 null。这意味着该属性不再持有任何值,也不再存在于图中。

为关系添加属性

如果你想添加关于 Jennifer 的就业信息,可以为 [:WORKS_FOR] 关系添加属性。该语句与为节点添加属性的语句类似

MATCH (:Person {name: 'Jennifer'})-[rel:WORKS_FOR]-(:Company {name: 'Neo4j'})
SET rel.startYear = date({year: 2018})
RETURN rel

结果如下:

关系

[:WORKS_FOR {startYear: 2018-01-01}]

行:1

删除关系

你可以使用 DELETE 子句删除关系和节点。但是,由于 Neo4j 符合 ACID 标准,如果节点仍然存在关系,你不能直接删除该节点。

因此,如果你想 删除一个节点(例如 Jennifer 的节点),需要先删除与其关联的所有关系

MATCH (j:Person {name:"Jennifer"})-[r]-(n)
DELETE r

请注意,箭头是无向的,因为无论方向如何,你都需要删除与 Jennifer 连接的所有关系。

结果显示以下消息:“Deleted 8 relationships”(删除了 8 个关系)。

删除节点

如果你已经在 上一步 中删除了所有关系,现在可以使用以下查询删除 Jennifer 的节点

MATCH (j:Person {name:"Jennifer"})
DELETE j

结果显示以下消息:“Deleted 1 node”(删除了 1 个节点)。

也可以使用 DETACH DELETE 在单个查询中删除节点及其所有关系。这种方法速度更快,但可控性较低

MATCH (m:Person {name: 'Mark'})
DETACH DELETE m

这将移除 Mark 节点上的所有附属关系以及节点本身。结果显示以下消息:“Deleted 1 node, deleted 2 relationships”(删除了 1 个节点,删除了 2 个关系)。

添加新数据

如果想向图中添加新数据,避免重复非常重要。例如,如果你尝试使用 CREATE 创建一个图中已存在的节点

CREATE (ann:Person {name: 'Ann'})
RETURN ann

你会产生重复数据。如果你 MATCH Ann 的节点

MATCH (ann:Person {name: 'Ann'})
RETURN ann

你会看到有两个节点包含了相同的信息

ann

(:Person {name: "Ann"})

(:Person {name: "Ann"})

行:2

但是,如果你使用 MERGE

MERGE (ann:Person {name: 'Ann'})
RETURN ann

Cypher 会返回现有的节点,而不会创建一个新的。

ann

(:Person {name: "Ann"})

行:1

你可以尝试使用 MERGE 来看看当图中不存在数据时它是如何工作的

MERGE (j:Person {name: 'Jack'})
RETURN j

你会收到消息“Created 1 node, set 1 property, added 1 label”(创建了 1 个节点,设置了 1 个属性,添加了 1 个标签)以及以下结果

j

(:Person {name: "Jack"})

行:1

这意味着图中没有找到 Jack,因此 MERGE 添加了他。

如果你想在两个现有节点之间添加关系,需要先 MATCH 它们,否则会创建重复数据。如果你使用 CREATE 来连接 Ann 和 Mark

CREATE (a:Person {name: 'Ann'})-[r:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
RETURN a, r, m

结果是你会复制 Ann 的节点,并创建一个新的 Mark 节点(因为它在 上一步 中被删除了),并在它们之间添加一个新的 IS_FRIENDS_WITH 关系。你会收到以下确认消息:“Created 2 nodes, created 1 relationship, set 2 properties, added 2 labels”(创建了 2 个节点,创建了 1 个关系,设置了 2 个属性,添加了 2 个标签)。

如果你改用 MERGE

MERGE (j:Person {name: 'Ann'})-[r:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
RETURN j, r, m

结果会导致更多重复。MERGE 尝试匹配整个模式,如果该模式不存在,则会创建它。

即使图中已经存在 Ann 和 Mark 的节点,但 (Ann)-[:IS_FRIENDS_WITH]→(Mark) 这个模式并不存在,因此所有元素都会被重新创建。

如果你创建了上述的重复数据,不需要在继续本教程前修复它。但是,如果你没有创建重复数据,则需要为 Mark 创建一个新节点(因为他在 上一步 中被删除了)。你可以使用 CREATEMERGE 来完成。

为了在不产生重复的情况下创建新关系,你需要先 MATCH Ann 和 Mark 的节点,然后 MERGE(或 CREATE)该关系

MATCH (a:Person {name: 'Ann'})
MATCH (m:Person {name: 'Mark'})
MERGE (a)-[r:IS_FRIENDS_WITH]->(m)
RETURN a, r, m

结论

在本教程中,你已经学习了如何更新节点、关系和属性。你还了解了如何从图中删除数据,以及如何在添加新数据时避免重复。

持续学习

如果你想了解更多关于如何更新图数据并找到最佳建模方式的信息,请参考

  • 数据建模 → 关于如何通过教程和参考资料开始数据建模的完整章节。