microblog | 微博客
原创
访问
0
获赞
0
评论
相关推荐
暂无数据
最新文章
暂无数据
热门文章
暂无数据

Neo4j Cypher 语法大全

bug写完了吗 10月07日 20:18:59 0 4 0
分类专栏: Neo4j 文章标签: Neo4j Neo4j语法

Neo4j Cypher 语法大全


一、核心概念

Neo4j 图数据库由三种核心实体构成:节点(Nodes)、关系(Relationships) 和 路径(Paths)。

实体 表示方式 特点
节点 (n:Label {prop: value}) 可有多个标签,属性以键值对存储
关系 -[r:TYPE {prop: value}]-> 必须有方向、起点、终点,且只能有一个类型
路径 p = (a)-[:R]->(b) 由节点和关系交替连接而成

Cypher 语法具有“可视化”特征:()-[]->() 的形状本身就描绘了要匹配的图模式。


二、读取与匹配

MATCH

指定要在数据库中搜索的图模式。

// 匹配特定标签和属性的节点 MATCH (n:Person {name: 'Alice'}) RETURN n // 匹配关系 MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name // 在关系上添加过滤条件(Cypher 25) MATCH (:Person {name: 'Anna'})-[r:KNOWS WHERE r.since < 2020]->(friend:Person) RETURN count(r) AS numberOfFriends

OPTIONAL MATCH

与 MATCH 类似,但如果模式部分缺失,会用 null 填充而不是过滤掉整行。

WHERE

为 MATCH、OPTIONAL MATCH 或 WITH 添加过滤条件。

MATCH (n:Person) WHERE n.age > 30 AND n.city = 'Beijing' RETURN n // 标签过滤 MATCH (n) WHERE n:Swedish RETURN n

可变长度关系

使用 * 或 {} 量化符匹配多跳路径。

// 1 到 3 跳 MATCH (a)-[:FOLLOWS*1..3]->(b) RETURN a, b // 最多 5 跳(最小值默认为 1) MATCH (a)-[:FOLLOWS*..5]->(b) RETURN a, b // 精确 2 跳 MATCH (a)-[:KNOWS*2]->(b) RETURN a, b

⚠️ 注意:无界遍历(*)在大图上可能导致性能爆炸,生产环境建议设置合理上限(通常 4–7 跳)。

最短路径

// 单条最短路径 MATCH p = shortestPath((a:User {id: 1})-[*..6]->(b:User {id: 99})) RETURN nodes(p), relationships(p), length(p) // 所有最短路径 MATCH p = allShortestPaths((a)-[*..10]->(b)) RETURN p

SHORTEST 选择器(Cypher 25)

MATCH p = SHORTEST 1 (:Person {name: 'Anna'})-[:KNOWS]-+(:Person {nationality: 'Canadian'}) RETURN p

三、写入与更新

CREATE

无条件创建节点和关系。不检查重复,重复执行会创建重复数据。

// 创建节点 CREATE (n:User {name: 'Alice', age: 32}) // 创建关系(需要先匹配两个端点) MATCH (a:User {name: 'Alice'}), (b:User {name: 'Bob'}) CREATE (a)-[:FOLLOWS {since: 2024}]->(b) // 创建完整路径 CREATE (a:User {name: 'Carol'})-[:WORKS_AT]->(c:Company {name: 'Acme'})

MERGE

“存在则匹配,不存在则创建”的 upsert 操作,是防止重复数据的关键。

// 合并节点 MERGE (n:User {email: 'alice@example.com'}) ON CREATE SET n.created = timestamp() ON MATCH SET n.lastSeen = timestamp() // 合并关系 MATCH (a:User {id: 1}), (b:User {id: 2}) MERGE (a)-[:FOLLOWS]->(b)

⚠️ 重要:MERGE 应基于唯一键。基于非唯一属性合并仍可能产生重复。

SET

更新节点标签或属性。

// 更新单个属性 MATCH (n:User {id: 1}) SET n.name = 'New Name' // 替换所有属性 SET n = {name: 'Alice', age: 30} // 添加/更新属性(保留现有属性) SET n += {city: 'Shanghai'} // 添加标签 SET n:Admin

DELETE / DETACH DELETE

// 删除关系 MATCH (a)-[r:FOLLOWS]->(b) WHERE a.id = 1 DELETE r // 删除节点(必须无关系) MATCH (n:User {email: 'old@example.com'}) DELETE n // 删除节点及其所有关系 MATCH (n:User {email: 'old@example.com'}) DETACH DELETE n

REMOVE

移除属性或标签。

MATCH (n:User {id: 1}) REMOVE n.status MATCH (n:User {id: 1}) REMOVE n:Admin

四、投影与聚合

RETURN

定义查询结果集,支持 AS 别名。

MATCH (n:Person) RETURN n.name AS name, n.age AS age

WITH

将查询部分链接起来,定义新的作用域。未列出的变量会被丢弃。

// 变量 b 在 WITH 之后不可用 MATCH (a:Person)-[:KNOWS]->(b:Person) WITH a, count(*) AS friends WHERE friends > 5 RETURN a.name, friends ORDER BY friends DESC // 使用 WITH * 保留所有变量 MATCH (a)-[:KNOWS]->(b) WITH * RETURN a, b

UNWIND

将列表展开为一系列行。

UNWIND [1, 2, 3] AS x RETURN x

排序与分页

MATCH (n:Person) RETURN n.name, n.age ORDER BY n.age DESC, n.name ASC SKIP 10 LIMIT 5

⚠️ ORDER BY 中不能使用 AS 别名,也不支持 SQL 的 NULLS LAST/FIRST。空值在升序中排最后,降序中排最前。


五、聚合函数

函数 说明
count(*) 统计所有行(包括 null)
count(expr) 统计非 null 值的行数
count(DISTINCT n.prop) 去重计数
collect(expr) 收集为列表,忽略 null
sum(), avg(), min(), max() 标准聚合

分组键:RETURN 或 WITH 中所有非聚合表达式都隐式成为分组键。


六、条件表达式

// 通用 CASE(if-elseif-else) RETURN n.title, CASE WHEN n.rating >= 8 THEN 'great' WHEN n.rating >= 6 THEN 'good' ELSE 'skip' END AS verdict // 简单 CASE(switch) RETURN n.status, CASE n.status WHEN 'A' THEN 'Active' WHEN 'I' THEN 'Inactive' ELSE 'Unknown' END AS label // 条件计数 sum(CASE WHEN r.rating = 5 THEN 1 ELSE 0 END) AS fiveStarCount

七、Null 处理

// 正确:使用 IS NULL / IS NOT NULL WHERE n.email IS NOT NULL WHERE n.email IS NULL // 错误:永远不匹配 WHERE n.email = null // coalesce() 返回第一个非空值 RETURN coalesce(n.nickname, n.name) AS displayName

null = null 的结果是 null(不是 true),WHERE 将 null 视为 false。


八、类型系统

属性类型

类型 说明
BOOLEAN 布尔
STRING 字符串
INTEGER 整数
FLOAT 浮点数
DATE / LOCAL TIME / ZONED TIME 日期/时间
LOCAL DATETIME / ZONED DATETIME 日期时间
DURATION 持续时间
POINT 空间点
UUID 仅 Cypher 25(Neo4j 2026.08+)
VECTOR<TYPE>(DIMENSION) 向量,维度 1–4096

列表类型

LIST<BOOLEAN NOT NULL>、LIST<STRING NOT NULL>、LIST<INTEGER NOT NULL> 等。

动态联合

INTEGER | FLOAT | STRING

类型转换

优先使用 OrNull 变体,转换失败返回 null 而非报错:

toIntegerOrNull(n.score) toFloatOrNull(n.score) toBooleanOrNull(n.flag) toStringOrNull(n.value)

类型谓词

WHERE n.value IS :: INTEGER NOT NULL

九、索引与约束

创建索引

// 单属性索引 CREATE INDEX FOR (n:User) ON (n.email) // 复合索引 CREATE INDEX FOR (n:User) ON (n.lastName, n.firstName) // 唯一约束 CREATE CONSTRAINT user_email_unique FOR (n:User) REQUIRE n.email IS UNIQUE

创建属性存在约束(企业版)

CREATE CONSTRAINT user_name_exists FOR (n:User) REQUIRE n.name IS NOT NULL

创建属性类型约束(企业版)

CREATE CONSTRAINT user_age_type FOR (n:User) REQUIRE n.age IS :: INTEGER

显示约束

SHOW CONSTRAINTS

十、管理子句

// 显示索引 SHOW INDEXES // 显示约束 SHOW CONSTRAINTS // 显示图类型(Cypher 25) SHOW GRAPH TYPES

十一、查询调优

// 查看执行计划(不执行) EXPLAIN MATCH (n:User) WHERE n.email = 'a@b.com' RETURN n // 执行并分析实际行数和数据库命中 PROFILE MATCH (n:User) WHERE n.email = 'a@b.com' RETURN n

关注执行计划中是否出现 NodeByLabelScan——这通常意味着索引未生效。


十二、实用要点

  1. 参数化查询:始终使用 $param 而非字符串拼接,防止注入并提升性能。
  2. CREATE vs MERGE:CREATE 无条件创建,MERGE 存在则复用。防止重复节点的核心是 MATCH 现有节点后再 MERGE 关系。
  3. count(*) vs count(n):前者统计所有行,后者只统计非 null 值。
  4. id() 已弃用:使用 elementId() 获取元素 ID。
  5. WITH 作用域:WITH 会丢弃未列出的变量,用 WITH * 保留全部。



评论区

登录后参与交流、获取后续更新提醒

目录
暂无数据