图数据库基础:Neo4j安装与配置、Cypher查询语言入门、节点与关系的创建
好,咱们正式开始动手了。这一章我带你把Neo4j装起来,然后写几条Cypher语句,把节点和关系创建出来。说白了,这是整个课程的地基。地基打不牢,后面那些金融规则模型根本跑不起来。
我个人习惯,学任何新技术,第一件事不是看书,而是先把环境搭好,跑通一个Hello World。这样心里才有底。咱们今天就这么干。
Neo4j的安装与配置
Neo4j有社区版和企业版。咱们课程用社区版就足够了,功能完全够用,而且免费。你想想看,一个生产级的图数据库,个人学习零成本,这多友好。
下载与安装
去Neo4j官网下载社区版。我建议你下载Desktop版本,也就是带图形界面的那个。为什么?因为对于初学者,可视化操作能帮你快速理解节点和关系是怎么一回事。我在项目中带新人时,都是让他们先用Desktop,等Cypher写熟了再切到Server版。
安装步骤很简单,双击安装包,一路Next就行。唯一要注意的是,安装路径不要带中文,也不要带空格。我曾经有个同事,安装路径写了个“图数据库”,结果启动时报错,折腾了半天才发现是路径编码问题。
启动与访问
安装完成后,启动Neo4j Desktop。你会看到一个界面,点击“New Project”,然后“Add Graph”,创建一个本地数据库。
创建好后,点击“Start”按钮。等几秒钟,状态变成绿色“Running”,就说明启动成功了。这时候,打开浏览器,访问 http://localhost:7474,就能看到Neo4j的Web管理界面。
neo4j。登录后系统会强制你修改密码。我建议你设一个自己记得住的密码,别设太复杂,学习阶段方便为主。
配置调整(可选)
如果你想把数据存到指定位置,或者调整内存大小,可以修改配置文件。在Desktop里,点击数据库右侧的“...”菜单,选择“Settings”,就能看到配置项。
我个人习惯,会把 dbms.memory.heap.initial_size 和 dbms.memory.heap.max_size 都设成1G。如果你的电脑内存不大,设成512M也行。别设太小,否则导入大量金融数据时会卡死。嗯,这里要注意,改完配置要重启数据库才能生效。
Cypher查询语言入门
Cypher是Neo4j的查询语言。你如果学过SQL,会发现Cypher的很多关键字跟SQL很像,比如 MATCH 对应 SELECT,WHERE 还是 WHERE。但Cypher更直观,它用 () 表示节点,用 [] 表示关系,用 -> 表示方向。
说白了,Cypher就是“画图”的语言。你写出来的语句,几乎就是一张图的样子。
基本语法结构
一个最简单的Cypher查询长这样:
MATCH (n) RETURN n LIMIT 25
这条语句的意思是:匹配所有节点,返回它们,但最多只返回25个。你刚装好Neo4j时,数据库是空的,所以什么也查不到。别急,咱们马上创建数据。
Cypher的语法核心就三个操作:
- CREATE:创建节点或关系
- MATCH:匹配已有的节点或关系
- RETURN:返回查询结果
你想想看,这不就是增删改查里的“增”和“查”吗?剩下的“删”和“改”,对应的是 DELETE 和 SET。很好记。
注释与风格
Cypher支持注释,用双斜杠 // 开头。我写Cypher时,习惯把复杂的查询拆成多行,每行加个注释,方便以后回头看。比如:
// 查找所有客户节点
MATCH (c:Customer)
// 返回客户姓名和ID
RETURN c.name, c.id
这个习惯帮我省了不少时间。有一次项目上线后,需要排查一个数据问题,我打开半年前写的Cypher脚本,因为有注释,五分钟就定位到了问题。要是没注释,估计得重新读一遍逻辑。
节点与关系的创建
好,重头戏来了。咱们在Neo4j里创建一些节点和关系。我拿金融场景举例,创建一个“客户”节点和一个“账户”节点,然后让它们之间建立“持有”关系。
创建节点
创建一个客户节点:
CREATE (c:Customer {name: '张三', age: 35, city: '北京'})
这条语句干了三件事:
- 创建了一个标签为
Customer的节点 - 给这个节点设置了三个属性:
name、age、city - 把节点赋值给变量
c
再创建一个账户节点:
CREATE (a:Account {accountId: '6222021234567890', balance: 50000.00})
你可能会问,为什么用 accountId 而不是直接用 id?因为 id 在Neo4j里是内部标识符,容易混淆。我在项目中吃过这个亏,后来就养成了习惯,业务标识符都加个前缀,比如 accountId、txnId。
创建关系
节点创建好了,但它们之间还没关联。咱们用关系把它们连起来:
MATCH (c:Customer {name: '张三'})
MATCH (a:Account {accountId: '6222021234567890'})
CREATE (c)-[:HOLDS {since: '2024-01-01', type: '储蓄卡'}]->(a)
这段代码的意思是:先找到张三这个客户,再找到那个账户,然后创建一条从客户指向账户的关系,关系类型是 HOLDS,并且带上两个属性:开户日期和账户类型。
-> 表示方向从左到右。你也可以用 <- 表示反向。如果关系没有方向,用 - 连接,但这种情况很少见。
批量创建
在实际项目中,你不会一条一条地创建数据。咱们用 FOREACH 或者直接写多条 CREATE 语句。比如:
CREATE (c1:Customer {name: '李四', age: 28, city: '上海'}),
(c2:Customer {name: '王五', age: 42, city: '深圳'}),
(a1:Account {accountId: '6222021111111111', balance: 120000.00}),
(a2:Account {accountId: '6222022222222222', balance: 80000.00})
然后创建关系:
MATCH (c1:Customer {name: '李四'}), (a1:Account {accountId: '6222021111111111'})
MATCH (c2:Customer {name: '王五'}), (a2:Account {accountId: '6222022222222222'})
CREATE (c1)-[:HOLDS {since: '2024-03-15'}]->(a1),
(c2)-[:HOLDS {since: '2024-06-20'}]->(a2)
MATCH 能找到对应的节点。如果节点不存在,MATCH 会返回空,后面的 CREATE 就不会执行。我曾经在导入一批客户数据时,因为一个客户ID写错了,导致整批关系都没创建成功,排查了半天才发现是匹配失败。
知识体系总览
下面这张图,把咱们这一章的核心知识点串起来了。你可以把它当作一个思维导图,方便回顾。
验证你的数据
创建完数据后,咱们查一下看看:
MATCH (c:Customer)-[r:HOLDS]->(a:Account)
RETURN c.name, a.accountId, a.balance, r.since, r.type
如果一切正常,你会看到类似这样的结果:
| c.name | a.accountId | a.balance | r.since | r.type |
|---|---|---|---|---|
| 张三 | 6222021234567890 | 50000.00 | 2024-01-01 | 储蓄卡 |
| 李四 | 6222021111111111 | 120000.00 | 2024-03-15 | 储蓄卡 |
| 王五 | 6222022222222222 | 80000.00 | 2024-06-20 | 储蓄卡 |
看到这个表格,说明你的Neo4j已经跑通了,Cypher也能写了,节点和关系也创建成功了。嗯,到这里,图数据库的基础就算打牢了。