Neo4j 知识速查表
核心概念
| 概念 | 说明 | 示例 |
|---|---|---|
| 节点(Node) | 图中的实体 | (p:Person {name: '张三'}) |
| 关系(Relationship) | 连接节点的边 | -[r:FRIEND]-> |
| 标签(Label) | 节点类型 | :Person, :Movie |
| 属性(Property) | 键值对数据 | {name: '张三', age: 30} |
| 路径(Path) | 节点和关系的序列 | (a)-[:FRIEND]->(b) |
Cypher 基础语法
节点模式
() -- 任意节点
(p) -- 节点变量为 p
(:Person) -- 标签为 Person 的节点
(p:Person) -- 变量为 p,标签为 Person
(p {name: '张三'}) -- 属性匹配的节点
(p:Person {name: '张三'}) -- 完整的节点模式
关系模式
--> -- 任意方向关系
-> -- outgoing 关系
<- -- incoming 关系
-[r]-> -- 关系变量为 r
-[:FRIEND]-> -- 类型为 FRIEND 的关系
-[r:FRIEND]-> -- 变量和类型
-[{since: '2020'}]-> -- 属性匹配的关系
完整模式
(a)-[r]->(b) -- a 到 b 的关系
(a)-[:FRIEND]->(b) -- 朋友关系
(a)-[:FRIEND*2]->(b) -- 2跳朋友关系
(a)-[:FRIEND*1..3]->(b) -- 1-3跳朋友关系
(a)-[:FRIEND|COLLEAGUE]->(b) -- 多种关系类型
CRUD 操作
创建(CREATE)
-- 创建节点
CREATE (p:Person {name: '张三', age: 30})
-- 创建关系
CREATE (a)-[:FRIEND {since: '2020-01-01'}]->(b)
-- 创建节点和关系
CREATE (a:Person {name: '张三'})-[:FRIEND]->(b:Person {name: '李四'})
-- 创建多个
CREATE (a:Person {name: 'A'}), (b:Person {name: 'B'})
查询(MATCH)
-- 查询所有
MATCH (n) RETURN n
-- 条件查询
MATCH (p:Person {name: '张三'}) RETURN p
-- 带 WHERE
MATCH (p:Person) WHERE p.age > 25 RETURN p
-- 查询关系
MATCH (p)-[r]->(other) RETURN p, r, other
-- 查询路径
MATCH path = (a)-[:FRIEND*2]->(b) RETURN path
更新(SET)
-- 更新属性
MATCH (p:Person {name: '张三'}) SET p.age = 31
-- 更新多个属性
MATCH (p:Person {name: '张三'}) SET p.age = 31, p.city = '北京'
-- 添加属性
MATCH (p:Person {name: '张三'}) SET p.email = '[email protected]'
-- 添加标签
MATCH (p:Person {name: '张三'}) SET p:Employee
-- 复制属性
MATCH (a), (b) WHERE id(a) = 1 AND id(b) = 2 SET a = b
删除(DELETE / REMOVE)
-- 删除关系
MATCH ()-[r:FRIEND]->() DELETE r
-- 删除节点(需先删关系)
MATCH (n) WHERE id(n) = 1 DELETE n
-- 级联删除(节点+关系)
MATCH (n) WHERE id(n) = 1 DETACH DELETE n
-- 删除属性
MATCH (p:Person) REMOVE p.email
-- 删除标签
MATCH (p:Person) REMOVE p:Employee
MERGE 语句
-- 合并节点(不存在则创建)
MERGE (p:Person {name: '张三'})
-- 合并关系
MATCH (a:Person {name: '张三'}), (b:Person {name: '李四'})
MERGE (a)-[r:FRIEND]->(b)
-- ON CREATE / ON MATCH
MERGE (p:Person {name: '张三'})
ON CREATE SET p.created = datetime()
ON MATCH SET p.lastSeen = datetime()
-- 合并带属性
MERGE (p:Person {name: '张三'})
ON CREATE SET p.age = 30
WHERE 子句
比较运算符
= -- 等于
<> -- 不等于
< -- 小于
> -- 大于
<= -- 小于等于
>= -- 大于等于
逻辑运算符
AND -- 与
OR -- 或
NOT -- 非
XOR -- 异或
字符串匹配
WHERE p.name STARTS WITH '张'
WHERE p.name ENDS WITH '三'
WHERE p.name CONTAINS '张'
WHERE p.name =~ '张.*' -- 正则表达式
其他条件
WHERE p.age IN [20, 25, 30]
WHERE p.email IS NULL
WHERE p.email IS NOT NULL
WHERE EXISTS(p.email)
WHERE p:Employee
聚合函数
count(n) -- 计数
count(DISTINCT n) -- 去重计数
sum(n.value) -- 求和
avg(n.value) -- 平均值
min(n.value) -- 最小值
max(n.value) -- 最大值
collect(n) -- 收集为列表
结果处理
排序
ORDER BY p.age -- 升序
ORDER BY p.age ASC -- 升序(显式)
ORDER BY p.age DESC -- 降序
ORDER BY p.city, p.age -- 多字段排序
分页
SKIP 10 -- 跳过前10条
LIMIT 10 -- 返回10条
SKIP 20 LIMIT 10 -- 第3页,每页10条
去重
RETURN DISTINCT p.city
函数参考
字符串函数
length(string) -- 字符串长度
substring(string, start, length) -- 子串
replace(string, old, new) -- 替换
toLower(string) -- 转小写
toUpper(string) -- 转大写
trim(string) -- 去空白
split(string, delimiter) -- 分割
join(list, delimiter) -- 连接
数学函数
abs(x) -- 绝对值
round(x) -- 四舍五入
floor(x) -- 向下取整
ceil(x) -- 向上取整
rand() -- 随机数
pow(x, y) -- 幂运算
sqrt(x) -- 平方根
列表函数
size(list) -- 列表大小
head(list) -- 第一个元素
tail(list) -- 除第一个外的元素
last(list) -- 最后一个元素
reverse(list) -- 反转
range(start, end) -- 范围列表
[x IN list WHERE cond] -- 过滤
[x IN list | expr] -- 映射
日期时间函数
datetime() -- 当前日期时间
date() -- 当前日期
time() -- 当前时间
datetime('2024-01-01') -- 解析日期时间
date().year -- 获取年份
date() + duration('P1D') -- 日期运算
节点和关系函数
id(n) -- 节点/关系 ID
labels(n) -- 节点标签列表
type(r) -- 关系类型
startNode(r) -- 关系的起始节点
endNode(r) -- 关系的目标节点
nodes(path) -- 路径中的节点
relationships(path) -- 路径中的关系
length(path) -- 路径长度
索引和约束
索引
-- 创建索引
CREATE INDEX person_name FOR (p:Person) ON (p.name)
CREATE RANGE INDEX person_age FOR (p:Person) ON (p.age)
CREATE TEXT INDEX person_city FOR (p:Person) ON (p.city)
-- 查看索引
SHOW INDEXES
-- 删除索引
DROP INDEX person_name
约束
-- 唯一性约束
CREATE CONSTRAINT person_email_unique FOR (p:Person) REQUIRE p.email IS UNIQUE
-- 存在性约束
CREATE CONSTRAINT person_name_exists FOR (p:Person) REQUIRE p.name IS NOT NULL
-- 节点键约束
CREATE CONSTRAINT person_key FOR (p:Person) REQUIRE (p.firstName, p.lastName) IS NODE KEY
-- 查看约束
SHOW CONSTRAINTS
-- 删除约束
DROP CONSTRAINT person_email_unique
路径函数
-- 最短路径
MATCH path = shortestPath((a)-[:FRIEND*]-(b))
-- 所有最短路径
MATCH paths = allShortestPaths((a)-[:FRIEND*]-(b))
-- 路径存在检查
MATCH (a), (b)
WHERE EXISTS((a)-[:FRIEND]-(b))
事务和会话
Python 示例
from neo4j import GraphDatabase
driver = GraphDatabase.driver("bolt://localhost:7687", auth=("neo4j", "password"))
# 自动提交
with driver.session() as session:
session.run("CREATE (p:Person {name: '张三'})")
# 读写事务
def create_person(tx, name):
return tx.run("CREATE (p:Person {name: $name}) RETURN p", name=name).single()
with driver.session() as session:
person = session.execute_write(create_person, "张三")
# 只读事务
def get_people(tx):
return list(tx.run("MATCH (p:Person) RETURN p.name AS name"))
with driver.session() as session:
people = session.execute_read(get_people)
driver.close()
数据导入
CSV 导入
-- 从 CSV 加载节点
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
CREATE (u:User {id: row.id, name: row.name, email: row.email})
-- 从 CSV 加载关系
LOAD CSV WITH HEADERS FROM 'file:///relationships.csv' AS row
MATCH (a:User {id: row.from_id})
MATCH (b:User {id: row.to_id})
CREATE (a)-[:FRIEND]->(b)
JSON 导入(使用 APOC)
-- 导入 JSON
call apoc.load.json('file:///data.json') YIELD value
CREATE (n:Node) SET n = value
性能优化
查询优化
-- 使用 EXPLAIN 查看执行计划
EXPLAIN MATCH (p:Person {name: '张三'}) RETURN p
-- 使用 PROFILE 查看实际执行
PROFILE MATCH (p:Person {name: '张三'}) RETURN p
-- 限制深度遍历
MATCH (p)-[:FRIEND*1..5]-(other) -- 好的做法
-- 避免
MATCH (p)-[:FRIEND*]-(other) -- 无限制深度
索引提示
-- 强制使用索引(不推荐常规使用)
MATCH (p:Person)
USING INDEX p:Person(name)
WHERE p.name = '张三'
RETURN p
常用查询模式
社交网络
-- 朋友的朋友(推荐)
MATCH (u:User {id: 'u001'})-[:FRIEND]-()-[:FRIEND]-(potential)
WHERE NOT (u)-[:FRIEND]-(potential)
RETURN potential, count(*) AS commonFriends
ORDER BY commonFriends DESC
-- 最短关系链
MATCH path = shortestPath(
(a:User {id: 'u001'})-[:FRIEND*]-(b:User {id: 'u002'})
)
RETURN path
权限检查
-- 检查用户权限
MATCH (u:User {id: 'u001'})-[:HAS_ROLE]->(role)-[:HAS_PERMISSION]->(perm)-[:ON]->(res)
WHERE res.name = '用户管理'
RETURN perm.action
时间序列
-- 最近7天的活动
MATCH (e:Event)
WHERE e.timestamp > datetime() - duration('P7D')
RETURN e
ORDER BY e.timestamp DESC