Java-167 Neo4j CQL 实战:CREATE/MATCH 与关系建模速通 案例实测
TL;DR
- 场景:用 Neo4j 在项目里落地节点与关系建模,需要可复制的 CQL。
- 结论:你的示例语法整体正确;注意变量/标签位序、属性逗号、关系方向与时间类型。
- 产出:SEO 摘要、版本矩阵、错误速查卡,可直接用于工程文档。

版本矩阵
| 版本 | 已验证 | 说明 |
|---|---|---|
| Neo4j 5.x(2023–2025) | 是 | 语法全兼容:多标签节点、属性 Map、关系属性、方向查询;推荐使用 DATE/LOCALDATETIME 等时间类型。 |
| Neo4j 4.x(LTS) | 是 | 同样支持示例语法;生产建议配合约束/索引与批量导入(LOAD CSV/驱动批写)。 |
| Neo4j 3.5(EOL) | 是 | 语法大体可用,但版本已停更;建议迁移到 4.x/5.x 以获得时间类型改进与生态支持。 |
CQL简介
CQL(Cypher Query Language)是Neo4j图形数据库专用的查询语言,就如同关系型数据库使用SQL(Structured Query Language)一样。以下是关于CQL的详细说明:
● 它是Neo4j图形数据库的原生查询语言
- 专门为图形数据模型设计
- 支持节点、关系和属性的高效查询
- 适用于社交网络、推荐系统等图形密集型应用场景
● 它是一种声明性模式匹配语言
- 用户只需描述要找什么,而不需指定如何查找
- 示例:MATCH (p:Person)-[:FRIENDS_WITH]->(f) RETURN p.name, f.name
- 自动优化查询执行路径
● 它遵循SQL语法设计原则
- 采用类似的语句结构(SELECT→RETURN, WHERE→WHERE)
- 保留SQL的关键概念(如DISTINCT, ORDER BY)
- 降低学习曲线,便于SQL开发者快速上手
● 它的语法设计注重可读性
- 使用直观的图形模式表示法
- 采用自然语言风格的关键词
- 示例查询一目了然:
MATCH (movie:Movie)<-[:ACTED_IN]-(actor:Actor) WHERE movie.title = 'The Matrix' RETURN actor.name - 支持注释和格式自由编排

CREATE 命令详解
CREATE 是 Neo4j 图数据库中最基础的创建节点命令,用于在图中创建新的节点实体。
基本语法结构
CREATE (<node-name>:<label-name>[{<property1-name>:<property1-Value>........<propertyn-name>:<propertyn-Value>
}])
参数说明
-
node-name(可选):
- 节点的变量名/引用名
- 在后续查询中可通过此名称引用该节点
- 示例:
(p)表示创建一个名为p的节点
-
label-name(必选):
- 节点标签,用于分类或类型标记
- 一个节点可以有多个标签(用冒号分隔)
- 示例:
:Person表示该节点具有Person标签
-
properties(可选):
- 节点的属性键值对,用大括号包裹
- 每个属性由属性名和属性值组成,用冒号分隔
- 多个属性间用逗号分隔
- 示例:
{name:'Alice', age:25}
使用示例
- 创建简单节点:
CREATE (:Person)
- 创建带属性的节点:
CREATE (:Person {name:'Bob', age:30, email:'bob@example.com'})
- 创建多个标签的节点:
CREATE (:Person:Employee {emp_id:'E1001'})
- 创建带变量名的节点(便于后续引用):
CREATE (p:Product {sku:'P100', price:99.99})
注意事项
- 节点名称仅在当前查询中有效
- 属性值可以是字符串、数字、布尔值等基本数据类型
- 执行CREATE后会立即在数据库中创建节点
- 批量创建大量节点时建议使用LOAD CSV或事务批量操作提高性能
应用场景
- 初始化数据库时创建基础节点
- 应用程序运行时动态添加新实体
- 数据迁移时批量导入节点
- 测试时创建模拟数据节点
语法说明:

举例语法:
CREATE(person:Person)
我们使用如下的命令创建数据:
CREATE (person:Person {cid:1,name:"wzk1",age:24,gender:0,character:"A",money:1000});
CREATE (person:Person {cid:2,name:"wzk2",age:20,gender:1,character:"B",money:800});
CREATE (person:Person {cid:3,name:"wzk3",age:18,gender:0,character:"A",money:500});

MATCH RETURN
MATCH
(
<node-name>:<label-name>
)
RETURN
<node-name>.<property1-name>,
...
<node-name>.<propertyn-name>

举例:
MATCH (person:Person) return person

MATCH (person:Person) return person.name, person.age

关系创建
使用现有节点创建没有属性的关系
MATCH (<node1-name>:<node1-label-name>),(<node2-name>:<node2-label-name>)
CREATE
(<node1-name>)-[<relationship-name>:<relationship-label-name>]->(<node2-
name>)
RETURN 相应的内容
语法说明:

创建关系
match(person:Person {name:"wzk1"}) ,(person2:Person {name:"wzk2"})
create(person)-[r:Couple]->(person2);

查询关系
match p = (person:Person {name:"wzk1"})-[r:Couple]->(person2:Person) return p;
match (p1:Person {name:"wzk1"})-[r:Couple]-(p2:Person) return p1,p2;
match (p1:Person {name:"wzk1"})-[r:Couple]-(p2:Person) return r;

使用现有节点创建有属性的关系
MATCH (<node1-label-name>:<node1-name>),(<node2-label-name>:<node2-name>)
CREATE
(<node1-label-name>)-[<relationship-label-name>:<relationship-name>
{<define-properties-list>}]->(<node2-label-name>)
RETURN <relationship-label-name>
其中<define-properties-list> 是分配给新创建关系的属性(名称 - 值对)的列表。
{
<property1-name>:<property1-value>,
<property2-name>:<property2-value>,
...
<propertyn-name>:<propertyn-value>
}
这里也进行举例子:
match(person:Person {name:"wzk1"}),(person2:Person {name:"wzk2"})
create(person)-[r:Couple{marry_date:"11/11/2025",price:55000}]->(person2)
return r;
当我们查询数据的时候

使用新节点创建没有属性的关系
CREATE
(<node1-label-name>:<node1-name>)
-[<relationship-label-name>:<relationship-name>]->
(<node1-label-name>:<node1-name>)
我们执行代码如下:
create(person1:Person {cid:4,name:"wzk4",age:18,gender:1,character:"A",money:5000})-[r:Friend]->(person2:Person {cid:7,name:"wzk5",age:28,gender:0,character:"B",money:1000})
创建完如下所示:

使用新节点创建有属性的关系
CREATE
(<node1-label-name>:<node1-name>{<define-properties-list>})
-[<relationship-label-name>:<relationship-name>{<define-properties-list>}]
->(<node1-label-name>:<node1-name>{<define-properties-list>})
关系和节点的属性可以使用的类型

错误速查
| 症状 | 根因 | 定位修复模板 |
|---|---|---|
写成 (Label:Var) 变量名与标签位序写反 | 搜索 MATCH (<node1-label-name>:<node1-name>) 这类片段 | 改为 (变量名:标签),如 MATCH (p:Person) |
{name:"a" age:1} 报语法错 | 属性间缺逗号 | 报错指向属性 Map,在键值间补逗号:{name:"a", age:1} |
{name="a"} 无法执行 | 用 = 赋值属性报错,含 mismatched input '=' | 改为冒号:{name:"a"} |
| 关系方向查不出数据 | 是 -> 建,查询用 -[]-> 方向不一致 | 查看创建与查询语句的箭头,要么统一方向,要么用无向 -[]- |
marry_date:"11/11/2025" 比较异常 | 把日期当字符串存,条件里涉及 <, > 或范围 | 用时间类型:marry_date: date("2025-11-11") |
| 重复人物被创建 | 缺唯一性约束,同名/同 cid 多次插入 | 先建约束:CREATE CONSTRAINT FOR (p:Person) REQUIRE p.cid IS UNIQUE |
| 写语句被拒绝/无效果 | 会话或实例处于只读 | 驱动/Browser 日志切换到写事务/有写权限的实例再 CREATE |
MATCH 后直接 RETURN 拿不到关系属性 | 只匹配到了节点,查询只投影了节点变量 | 同时匹配并投影关系:MATCH (a)-[r:Couple]->(b) RETURN r, a, b |
| 批量导入很慢 | 单条 CREATE 循环执行,计划显示多次写入 | 用 LOAD CSV/驱动批写 + 适当索引/约束 |
其他系列
🚀 AI篇持续更新中(长期更新)
AI炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用AI工具指南!
AI-调查研究-108-具身智能 机器人模型训练全流程详解:从预训练到强化学习与人类反馈
🔗 AI模块直达链接
💻 Java篇持续更新中(长期更新)
Java-154 深入浅出 MongoDB 用Java访问 MongoDB 数据库 从环境搭建到CRUD完整示例
MyBatis 已完结,Spring 已完结,Nginx已完结,Tomcat已完结,分布式服务正在更新!深入浅出助你打牢基础!
🔗 Java模块直达链接
📊 大数据板块已完成多项干货更新(300篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!
大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT案例 详解
🔗 大数据模块直达链接
