更新图数据
本教程展示了如何通过更改、删除和添加节点、关系及属性来更新图中的信息。它还介绍了如何避免重复数据。
创建数据集
在 创建免费的 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 个标签的图。
为节点添加属性
如果你想为名叫 Jennifer 的人添加生日,可以使用以下查询将此信息作为 属性 添加进去
MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-01')
RETURN p
此查询执行以下操作
-
使用
MATCH子句找到 Jennifer 的节点。 -
使用
SET创建新属性birthday(语法为variable.property)并设置其值。 -
使用
RETURN返回 Jennifer 的节点,以便确认信息已正确更新。
这是表格形式的查询结果
| p |
|---|
|
行:1 |
更新属性
要更改 Jennifer 的生日,你可以使用上一个示例中相同的查询再次找到 Jennifer 的节点,并通过 SET 子句设置不同的日期来修改属性值
MATCH (p:Person {name: 'Jennifer'})
SET p.birthdate = date('1980-01-02')
RETURN p
这是表格形式的查询结果
| p |
|---|
|
行: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
结果如下:
| 关系 |
|---|
|
行: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 |
|---|
|
|
行:2 |
但是,如果你使用 MERGE
MERGE (ann:Person {name: 'Ann'})
RETURN ann
Cypher 会返回现有的节点,而不会创建一个新的。
| ann |
|---|
|
行:1 |
你可以尝试使用 MERGE 来看看当图中不存在数据时它是如何工作的
MERGE (j:Person {name: 'Jack'})
RETURN j
你会收到消息“Created 1 node, set 1 property, added 1 label”(创建了 1 个节点,设置了 1 个属性,添加了 1 个标签)以及以下结果
| j |
|---|
|
行: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 创建一个新节点(因为他在 上一步 中被删除了)。你可以使用 |
为了在不产生重复的情况下创建新关系,你需要先 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
持续学习
如果你想了解更多关于如何更新图数据并找到最佳建模方式的信息,请参考
-
数据建模 → 关于如何通过教程和参考资料开始数据建模的完整章节。