参考文档:https://neo4j.com/developer/cypher-basics-ii/
CQL:就是cypher query language,图数据库的查询语言。本节目标:以创建如下的图结构为例,学习增删查改语句。
1、Jennifer likes Graphs
2、Jenifer is friend with Michael
3、Jennifer works for neo4j
一般为名词性词语,创建时可以取一个别名,作为后续返回以及属性访问等操作的基础。
一般是谓词结构,单向。但是,当不确定关系的方向时,最好采用无箭头的方式match:
文中指出,如果不加别名,那么就不会定义该关系,而是当做一个变量看待,然后遍历所有的关系,也就是说只要两个match的节点具有任何关系都可以作为结果返回。
属性是添加到节点或者关系后面,用花括号括起来的键值对。用以对节点或者关系进行补充,例如:
1、创建主人公节点Jennifer:
create (host:Person{name:Jennifer}) return host
create(friend:Person{name:'Mark'}) return friend
match (host:Person{name:'Jennifer'})
match(friend:Person{name:'Mark'})
create (host)-[rel:IS_FRIEND_WITH]->(friend)
为什么要用两个match再创建呢,因为这样是先查到两个节点,再在两个节点之间创建关系,但是如果直接用create(例如下面这样),就会重新创建两个新的节点。
增加Jennifer节点的生日属性:
match (host:Person{name:'Jennifer'})
set host.birthday = '2020-1-1'
return host
match (host:Person{name:'Jennifer'})
set host.birthday = '20202-2'
return host
关系属性修改:增加服役的时间,2018,属性用大括号以键值对的形式呈现,但是节点访问时可以直接用点号访问。
match (:Person{name:'Jennifer'})-[rel:WORKS_FOR]->(:Company{name:'Neo4j'})
set rel.stary_year = 'year:2018' return rel
ecause Neo4j is ACID-compliant, you cannot delete a node if it still has relationships. If you could do that, then you might end up with a relationship pointing to nothing and an incomplete graph. We will walk through how to delete a disconnected node, a relationship, as well as a node that still has relationships.
删除关系:
Match (:Person{name:’Jennifer’})-[r:IS_FRIEND_WITH]->(Person{name:’Mark’})
delete r
match (p:Person{name:'Mark'}) delete p
Neo4j具有耐酸性(胡乱翻译的,原文: ACID-compliant),他不允许我们删除一个带有关系的节点,但是可以用detach delete来删除一个节点以及这个节点连接的所有关系。
首先,创建Tom节点,然后尝试两种删除
match (p:Person{name:'Jennifer'})
create (p)-[:IS_FRIEND_WITH]->(:Person{name:'Tom'})
直接delete:
match (p:Person{name:'Tom'}) delete p
删除属性的两种方式:remove、set to null
match (p:Person{name:'Kitty'}) remove p.name return p
match (p:Person{name:'Jennifer'}) set p.birthday=null
在节点上使用Merge:
merge (p:Person{name:'Mark'}) return p
再次merge,仍然只有一个Mark,但是可以更新属性值。如果create就会有两个
Merge 关系:
MATCH (j:Person {name: 'Jennifer'})
MATCH (m:Person {name: 'Mark'})
MERGE (j)-[r:IS_FRIENDS_WITH]->(m)
RETURN j, r, m
但是,如果采用下面的做法就会产生重复的节点,因为两者之间没有建立关系,但是merge考虑的是整体,这个pattern是新的,所以就创建。
假如,你想用merge来排除数据的复制,但是又想针对创建和match这两个可能的结果采取不同的动作,可以采用on match 和on create:
类型 | 符号 |
---|---|
节点 | 小括号( ) |
关系 | 中括号[ ] |
属性 | 大括号{ } |
在实体中,属性用大括号的方式给出,但是访问时直接用点号即可。
如果数据库中有节点、关系,合理的使用merge可以避免duplicate,但是create就是直接创建而不考虑数据库中是否有无相应的节点。另外,如果不事先match,那么merge不会在创建和更新之间混合,当有局部不存在时,会直接创建一个新的pattern包括node-relationship-node整体。实验表明:
当事先条件不存在,或者条件存在但是years!=9时,那么这个操作就等价于create。
但是,假如先match在merge,那么不会创建新的节点,而是只更新关系及关系属性。
merge (p:Person{name:'Jennifer'})-[r:IS_FRIEND_WITH{years:9}]->
(m:Person{name:'Mark'})
Cypher never produces a partial mix of matching and creating within a pattern. To avoid a mix of match and create, you need to match any existing elements of your pattern first before doing a merge on any elements you might want to create, just as we did in the statement above.