Merge 语法
Merge 语法能够避免重复创建节点或者关系,如创建节点的时候可以避免重复创建
MERGE (mark:Person {name: 'Mark'})
RETURN mark
但是需要注意,创建关系的时候
MATCH (j:Person {name: 'Jennifer'})
MATCH (m:Person {name: 'Mark'})
MERGE (j)-[r:IS_FRIENDS_WITH]->(m)
RETURN j, r, m
如上Cypher语句不会产生重复的节点,因为首先会通过两个match,获取到指定节点,再查询是否包含关系,如果不存在关系则创建。
但是如果使用下面这个语句
MERGE (j:Person {name: 'Jennifer'})-[r:IS_FRIENDS_WITH]->(m:Person {name: 'Mark'})
RETURN j, r, m
则会产生重复节点,因为merge检查是否存在是针对整个pattern的,当前图中即使存在了Person {name: 'Jennifer'} 节点和Person {name: 'Mark'}节点,但是因为它们之间还未建立连接,因此merge判定该pattern不存在,因此会全部重新创建。
如果要根据Merge时,是重新创建还是match到已有的pattern来update不同的的属性,可以用on create 和on match ,语法如下
MERGE (m:Person {name: 'Mark'})-[r:IS_FRIENDS_WITH]-(j:Person {name:'Jennifer'})
ON CREATE SET r.since = date('2018-03-01')
ON MATCH SET r.updated = date()
RETURN m, r, j
where 语法
- 正则表达式
MATCH (p:Person)
WHERE p.name =~ 'Jo.*'
RETURN p.name
- pattern 作为查询条件
MATCH (p:Person)-[r:IS_FRIENDS_WITH]->(friend:Person)
WHERE p.name = 'Jennifer'
AND NOT exists((friend)-[:WORKS_FOR]->(:Company))
RETURN friend.name
- optional match
类似于SQL中的outer join,如果匹配则返回数据,否则返回null
查询名字开头为j且可能为某个公司工作的人
MATCH (p:Person)
WHERE p.name STARTS WITH 'J'
OPTIONAL MATCH (p)-[:WORKS_FOR]-(other:Company)
RETURN p.name, other.name
返回结果如下: joe他没有为一个公司工作,但他依旧返回了,如果去掉optional,则不会返回。
4 复杂pattern 查询
//Query1: find who likes graphs besides Jennifer
MATCH (j:Person {name: 'Jennifer'})-[r:LIKES]-(graph:Technology {type: 'Graphs'})-[r2:LIKES]-(p:Person)
RETURN p.name
//Query2: find who likes graphs besides Jennifer that she is also friends with
MATCH (j:Person {name: 'Jennifer'})-[:LIKES]->(:Technology {type: 'Graphs'})<-[:LIKES]-(p:Person),
(j)-[:IS_FRIENDS_WITH]-(p)
RETURN p.name
- 子查询
MATCH (person:Person)
where exits{
MATCH (person)-[:HAS_DOG]->(:Dog)
WHERE person.name = dog.name
}
RETURN person.name as name
MATCH (person:Person)
where exits{
MATCH (person)-[:HAS_DOG]->(:Dog)
WHERE EXITS{
MATCH (dog)-[:HAS_TOY]->(toy:Toy)
where toy.name = 'Banana'
}
}
RETURN person.name as name
Order by 语法
如果在with后使用order by,则是只在with当前阶段进行排序,不保证后续的有序性
MATCH (n)
WITH n ORDER BY n.age
RETURN collect(n.name) AS names
result:
["C","A","B"]
set 语法
case when
MATCH (n {name:'Andy'})
set (case when n.age=36 then n END).workdsIn = 'Malmo'
return n.name,n.worksIn
添加属性
MATCH (p {name:'Peter'})
SET p+={age:30,hungry:true,position:'Entrepreneur'}
return p.name,p.age,p.hungry,p.position
设置Label
MATCH (n {name: 'Stefan'})
SET n:German
RETURN n.name, labels(n) AS labels
FOREACH 语法
将路径上的所有节点的marked属性设为True
MATCH p = (start)-[*]->(finish)
WHERE start.name = 'A' and finish.name = 'D'
FOREACH (n IN nodes(p) | SET n.marked = true)