7.4 KiB
Neo4j的cyhper基本语法
1. 创建节点和关系
1.1创建节点
create (n)
create (n),(m)
create(n:Movie)
create(n:Movie:Person)
# 创建一个带有标签(Person)和属性(name:'TEST-NAME', age:1)的节点
create(n:Person {name:'qiusj',age:18})
# 返回创建的节点
CREATE(n:TEST {name:'TEST-NAME1', age:2}) return n
1.2 创建关系
# 创建两个节点之间的关系
MATCH (a:TEST),(b:TEST)
WHERE a.name = 'TEST-NAME' AND b.name = 'TEST-NAME1'
CREATE (a)-[r:RELTYPE] -> (b)
RETURN r
# 创建两个节点之间的关系,并调用两个节点的属性:
MATCH (a:TEST),(b:TEST)
WHERE a.name = 'TEST-NAME' AND b.name = 'TEST-NAME1'
CREATE (a)-[r:RELTYPE { name: a.name + b.name}] -> (b)
RETURN r
1.3 merge 命令
在Neo4j数据库中,MERGE命令是一个非常强大的工具,它结合了CREATE和MATCH命令的功能。当你需要确保一个特定的节点或关系在图中存在时,MERGE命令就显得尤为重要。如果该节点或关系不存在,MERGE将会创建它;如果已经存在,MERGE则会匹配到这个现有的元素。
如果这个节点已经存在,那么MERGE命令的作用就相当于MATCH命令。判断是否存在的方式是表达式中所有的属性组合匹配的:如 MERGE (p:Person {name: 'Alice'}) RETURN p;只要在已有的Person中name属性没有等于'Alice'的就是不存在,MERGE (p:Person {name: 'Alice,age:18}) 则要求现有的Person中的name和age都不相同才表示不存在
MERGE (robert:Person { name: 'Robert' })
RETURN robert, labels(robert)
MERGE还可以用来创建节点之间的关系。如果两个节点之间的关系不存在,MERGE会创建这个关系。例如,以下命令会创建一个名为"Robert"的Person节点和一个名为"hanscal"的Person节点之间的FAMILY关系:
MATCH (n:Person { name: 'Robert' }), (m:Person { name: "hanscal" })
MERGE (n)-[r:FAMILY]->(m)
RETURN n.name, type(r), m.name
使用ON CREATE和ON MATCH
MERGE命令可以与ON CREATE和ON MATCH子句结合使用,这允许你根据元素是被匹配到还是被创建来执行不同的操作。例如,以下命令在创建新节点时设置一个时间戳属性:
MERGE (c:Person { name: 'Hanscal' })
ON CREATE SET c.create = timestamp()
RETURN c.name, c.create
如果节点"Hanscal"已经存在,则不会设置任何属性。相反,如果使用ON MATCH,则只有在匹配到节点时才会设置属性。
批量操作
MERGE命令也可以用于批量操作,快速创建大量的节点和关系。例如,以下命令会将所有Person节点的出生地属性与City节点连接起来,并创建BORN_IN关系:
MATCH (person:Person)
MERGE (city:City { name: person.bornIn })
MERGE (person)-[r:BORN_IN]->(city)
RETURN person.name, person.bornIn, city
总的来说,MERGE命令在确保数据一致性和避免重复创建相同的元素时非常有用。
约束与 MERGE 命令的关系
-
唯一性约束:确保指定标签的节点在特定属性上具有唯一性,是 Neo4j 保证数据完整性的重要机制
-
MERGE 命令行为:
- 若匹配条件的节点 / 关系存在,则返回现有节点 / 关系
-
若不存在,则创建新的节点 / 关系
-
冲突点:当 MERGE 的匹配条件触发唯一性约束时,会因重复数据导致操作失败
1.4 添加属性
方案 1:使用 MATCH 而非 MERGE(推荐)
MATCH (p:Person {name: 'Robert'})
SET p.age = 18
RETURN p;
方案 2:修改 MERGE 语句避免重复创建
# 安全的MERGE写法(先检查节点是否存在)
MERGE (p:Person {name: 'Robert'})
# 仅当节点不存在时才创建新属性(避免冲突)
ON CREATE SET p.create = timestamp()
# 无论是否创建都可以设置属性(不会触发约束)
SET p.money = 1
RETURN p;
1.5 修改节点的关系类型
在 Neo4j 中,关系类型(Relationship Type)是不可变的,无法直接修改。若要更改关系类型,需通过以下步骤实现:创建新关系 → 复制属性 → 删除旧关系。以下是详细方法:
方法一:使用 Cypher 手动转换关系类型
// 示例:将 KNOWS 关系转换为 FRIEND 关系
MATCH (p1:Person)-[r:KNOWS]->(p2:Person)
WHERE p1.name = 'Alice' AND p2.name = 'Bob'
// 创建新类型的关系
CREATE (p1)-[r2:FRIEND]->(p2)
// 复制旧关系的所有属性到新关系
SET r2 = r
// 删除旧关系
DELETE r
RETURN p1, r2, p2;
2.查询语法
match、optional match、where、start和aggregation聚合
2.1 match语法
简单查询
# 查询所有节点
match (n) return n
# 查询指定标签的节点
match (n:Person) return n
# 查询指定标签和属性的节点
match (n:Person {name:"张三"}) return n
关系查询
# 查询出度1的节点
match (n:Person{name:"张三"})-[r]->(m) return m
match (n:Person{name:"zhangsan"})-->(m) return m
# 查询入度1节点:
match (n:Person{name:"zhangsan"})<-[r]-(m) return m
match (n:Person{name:"zhangsan"})<--(m) return m
3.删除节点
-
删除无关系的孤立节点
使用
DELETE语句直接删除节点// 删除单个节点(无关系) MATCH (p:Person {name: 'Alice'}) DELETE p; // 批量删除符合条件的节点 MATCH (p:Person) WHERE p.age < 18 DELETE p; -
删除带有关联关系的节点
需先删除关系,再删除节点。可使用
DETACH DELETE一次性完成:// 方法1:分步删除(手动删除关系) MATCH (p:Person {name: 'Bob'})-[r]->() DELETE r; // 先删除所有外出关系 MATCH (p:Person {name: 'Bob'}) DELETE p; // 再删除节点 // 方法2:使用DETACH DELETE(推荐) MATCH (p:Person {name: 'Charlie'}) DETACH DELETE p; // 自动删除节点及其所有关系 -
基于关系条件删除节点
删除符合特定关系条件的节点:
// 删除所有没有朋友的人(无FOLLOWS关系) MATCH (p:Person) WHERE NOT (p)-[:FOLLOWS]->() DELETE p; // 删除被超过100人关注的明星节点 MATCH (s:Star)<-[r:FOLLOWS]-() WITH s, count(r) as followers WHERE followers > 100 DETACH DELETE s; -
删除整个标签的所有节点
// 删除所有Person节点及其关系 MATCH (p:Person) DETACH DELETE p; // 更安全的分批删除方法 CALL apoc.periodic.iterate( "MATCH (p:Person) RETURN p", "DETACH DELETE p", {batchSize:1000, parallel:false} ); -
删除节点并返回删除数量
MATCH (p:Person) WHERE p.lastLogin < date("2023-01-01") DETACH DELETE p RETURN count(*) as deletedNodes;
4. 删除关系
场景一:删除特定关系
// 方法1:通过匹配节点和关系类型删除
MATCH (p1:Person {name: 'Alice'})-[r:FRIEND]->(p2:Person {name: 'Bob'})
DELETE r;
// 方法2:使用更精确的匹配条件(如属性)
MATCH (p1:Person)-[r:WORKS_ON {projectId: 'PRJ-123'}]->(p2:Project)
DELETE r;
场景二:只有查询返回的ID
// 方法1:使用关系ID直接删除
MATCH ()-[r]->()
WHERE id(r) = 5678 // 替换为实际关系ID
DELETE r; // 仅删除关系,保留节点
// 方法2:验证关系后删除
MATCH ()-[r]->()
WHERE id(r) = 5678
RETURN r; // 先查询确认关系是否存在
// 确认无误后执行删除
MATCH ()-[r]->()
WHERE id(r) = 5678
DELETE r;