Cypher更新数据


前言

前面你学习了如何在Cypher中表示节点、关系、标签、属性和模式。本节通过介绍如何用Cypher更新和删除数据为你的知识增加了一个层次。

虽然这些是标准的CRUD(创建、更新和删除)操作,但有些东西在图中的功能与其他类型的数据库有点不同。在我们进行的过程中,你可能会认识到一些相似和不同之处。

1. 用Cypher更新数据

你可能已经在数据中拥有一个节点或关系,但你想修改它的属性。你可以通过MATCH你想找到的模式并使用SET关键字来添加、删除或更新属性来做到这一点。

到目前为止,使用上面的例子数据集,你可以更新Jennifer的节点,增加她的出生日期。接下来的Cypher语句显示了如何做到这一点。

  • 首先,你需要找到Jennifer的现有节点。

  • 接下来,使用SET来创建新的属性(语法为variable.property)并设置其值。

  • 最后,你可以返回Jennifer的节点以确保信息被正确更新。

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

如果你想改变Jennifer的出生日期,你可以使用上述相同的查询,再次找到Jennifer的节点,并在SET子句中放入不同的日期。

你还可以更新Jennifer与公司节点的WORKS_FOR关系,以包括她开始在那里工作的年份。要做到这一点,你可以使用与上面类似的语法来更新节点。

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

2. 用Cypher删除数据

另一个要介绍的操作是如何在Cypher中删除数据。对于这个操作,Cypher使用DELETE关键字来删除节点和关系。它与其他语言如SQL中的删除数据非常相似,但有一个例外。

因为Neo4j是符合ACID标准的,如果一个节点仍有关系,你不能删除它。如果你能做到这一点,那么你可能会出现一个关系没有指向任何东西和一个不完整的图。

删除一个关系

要删除一个关系,你需要找到你想删除的关系的开始和结束节点,然后使用DELETE关键字,如下面的代码块所示。让我们继续,暂时删除Jennifer和Mark之间的IS_FRIENDS_WITH关系。我们将在以后的练习中重新添加这种关系。

MATCH (j:Person {name: 'Jennifer'})-[r:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
DELETE r

删除一个节点

要删除一个没有任何关系的节点,你需要找到你想删除的节点,然后使用DELETE关键字,就像你对上面的关系一样。你可以暂时删除马克的节点,以后再把他带回来。

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

删除一个节点和它的关系

与其运行最后两个查询来删除IS_FRIENDS_WITH关系和Mark的Person节点,你实际上可以运行一个语句来同时删除节点和其关系。正如上面提到的,Neo4j是符合ACID标准的,所以它不允许删除一个仍有关系的节点。使用DETACH DELETE语法告诉Cypher删除该节点的任何关系,以及删除该节点本身。

该语句看起来就像下面的代码。首先,你在数据库中找到马克的节点。然后,DETACH DELETE行删除马克节点的任何现有关系,然后再删除该节点。

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

删除属性

你也可以删除属性,但不是使用DELETE关键字,你可以使用其他一些方法。

第一个选择是在属性上使用REMOVE。这告诉Neo4j,你想从节点上完全删除该属性,不再存储它。

第二个选择是使用前面的SET关键字,将属性值设置为null。与其他数据库模型不同,Neo4j不存储空值。相反,它只存储对你的数据有意义的属性和值。这意味着,你可以在图中的各种节点和关系上拥有不同类型和数量的属性。

为了向你展示这两个选项,让我们看看每个选项的代码

//delete property using REMOVE keyword
MATCH (n:Person {name: 'Jennifer'})
REMOVE n.birthdate

//delete property with SET to null value
MATCH (n:Person {name: 'Jennifer'})
SET n.birthdate = null

3. 使用MERGE避免重复的数据

前面简单提到,在Cypher中,有一些方法可以避免创建重复的数据。其中一个方法是使用MERGE关键字。MERGE做了一个 "选择或插入 "操作,首先检查数据是否存在于数据库中。如果它存在,那么Cypher将其原样返回,或者在现有的节点或关系上做任何你指定的更新。如果数据不存在,那么Cypher将用你指定的信息创建它。

在一个节点上使用MERGE
首先,让我们看一个例子,用下面的查询把马克加回到我们的数据库中。你可以使用MERGE来确保Cypher检查数据库中是否有Mark的现有节点。由于你在前面的例子中删除了Mark的节点,Cypher将不会找到现有的匹配,并将创建新的节点,其名称属性设置为’Mark’。

MERGE (mark:Person {name: 'Mark'})
RETURN mark

4. UNION

如果你想把两个具有相同结果结构的语句的结果结合起来,你可以使用UNION [ALL]。

例如,下面的语句同时列出了演员和导演。

MATCH (actor:Person)-[r:ACTED_IN]->(movie:Movie)
RETURN actor.name AS name, type(r) AS type, movie.title AS title
UNION
MATCH (director:Person)-[r:DIRECTED]->(movie:Movie)
RETURN director.name AS name, type(r) AS type, movie.title AS title

WITH

在Cypher中,你可以将语句的片段连锁起来,类似于数据流管道中的做法。每个片段都在前一个片段的输出上工作,其结果可以反馈到下一个片段。只有在WITH子句中声明的列才能在后续的查询部分中使用。

WITH子句被用来结合各个部分,并声明哪些数据从一个部分流向另一个部分。WITH与RETURN子句类似。不同的是,WITH子句并没有完成查询,而是为下一个部分的输入做准备。表达式、聚合、排序和分页的使用方法与RETURN子句相同。唯一的区别是所有的列都必须是别名。

在下面的例子中,收集某人出现的电影,然后过滤掉那些只出现在一部电影中的电影。

MATCH (person:Person)-[:ACTED_IN]->(m:Movie)
WITH person, count(*) AS appearances, collect(m.title) AS movies
WHERE appearances > 1
RETURN person.name, appearances, movies
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值