第二章 图数据库入门:Neo4j安装与配置、Cypher查询语言基础、节点与关系的创建
好,咱们进入正题。上一章我们聊了图计算在信贷审批里到底能干啥,说白了就是解决「关系」的问题。那工欲善其事,必先利其器。这一章,我们就来亲手搭一个图数据库环境,学学怎么跟它对话。
我个人习惯用 Neo4j,社区版免费,上手快,文档也全。你想想看,信贷审批里那些客户、手机号、设备、联系人,本质上就是节点和关系。Neo4j 正好就是干这个的。
2.1 Neo4j 安装与配置
安装这事,其实没那么玄乎。我最早接触 Neo4j 的时候,还踩过 Java 版本不兼容的坑。嗯,这里要注意:Neo4j 依赖 Java 环境,建议用 Java 11 或 17。
2.1.1 下载与安装
去官网下载社区版,或者直接用 Docker 拉镜像。我个人更推荐 Docker,省心,不会污染本地环境。
# 拉取镜像
docker pull neo4j:4.4-community
# 启动容器,映射端口和存储目录
docker run -d \
--name neo4j-credit \
-p 7474:7474 -p 7687:7687 \
-v /data/neo4j:/data \
-e NEO4J_AUTH=neo4j/yourpassword \
neo4j:4.4-community
7474 是浏览器访问端口,7687 是 Bolt 协议端口,咱们程序连数据库就用这个。我在项目中遇到过有人只开了 7474,结果程序连不上,排查了半天才发现是 7687 没开。
2.1.2 验证安装
启动后,浏览器打开 http://localhost:7474,输入账号密码。看到那个熟悉的「Connect」按钮,就说明成了。
进去之后,你会看到一个空白的查询窗口。别慌,这就是我们接下来要用的主战场。
2.2 Cypher 查询语言基础
Cypher 是 Neo4j 的查询语言,说白了就是图数据库的 SQL。但比 SQL 更直观,因为它直接描述「节点-关系-节点」这种结构。
你想想看,在信贷场景里,我们要查「张三的所有联系人」,用 SQL 得写 JOIN 三张表,用 Cypher 呢?一行搞定。
2.2.1 基本语法结构
Cypher 的核心语法就几个符号:
()表示节点[]表示关系->或-表示方向
举个例子:
// 查询所有客户节点
MATCH (c:Customer)
RETURN c
// 查询张三的所有直接联系人
MATCH (c:Customer {name: '张三'})-[:CONTACT]->(contact:Person)
RETURN contact
看到没?MATCH 就是「匹配」,RETURN 就是「返回」。跟 SQL 的 SELECT 差不多,但更直观。
2.2.2 常用命令
| 命令 | 作用 | 信贷场景举例 |
|---|---|---|
| MATCH | 匹配已有模式 | 查找逾期客户 |
| CREATE | 创建节点或关系 | 新增客户信息 |
| MERGE | 匹配或创建(防重复) | 导入设备信息 |
| DELETE | 删除节点或关系 | 移除错误数据 |
| SET | 更新属性 | 修改客户状态 |
我个人最常用的是 MERGE。为什么?因为信贷数据经常重复导入,用 CREATE 会报错,用 MERGE 就安全多了。
2.3 节点与关系的创建
好,理论说完了,咱们动手。我模拟一个信贷场景:客户、手机号、设备之间的关系。
2.3.1 创建节点
先创建几个客户节点:
// 创建客户节点
CREATE (c:Customer {
id: 'C001',
name: '张三',
age: 35,
credit_score: 720,
application_date: date('2024-01-15')
})
// 创建手机号节点
CREATE (p:Phone {
number: '13800138001',
operator: '中国移动',
activation_date: date('2023-06-01')
})
// 创建设备节点
CREATE (d:Device {
imei: '123456789012345',
brand: 'Apple',
model: 'iPhone 14',
first_seen: datetime('2024-01-15 10:30:00')
})
这里要注意:节点标签(如 Customer)首字母大写,属性名用小写驼峰。这是我个人的编码习惯,团队统一风格很重要。
2.3.2 创建关系
节点建好了,得连起来才有意义。在信贷场景里,关系就是「谁用了哪个手机号」、「哪个设备登录了哪个账号」。
// 张三使用手机号
MATCH (c:Customer {id: 'C001'})
MATCH (p:Phone {number: '13800138001'})
CREATE (c)-[:USES {
start_date: date('2024-01-15'),
status: 'active'
}]->(p)
// 手机号关联设备
MATCH (p:Phone {number: '13800138001'})
MATCH (d:Device {imei: '123456789012345'})
CREATE (p)-[:REGISTERED_ON {
first_time: datetime('2024-01-15 10:30:00'),
last_time: datetime('2024-01-15 10:30:00')
}]->(d)
你想想看,如果张三逾期了,风控系统要查他名下所有手机号关联的设备,再查这些设备关联的其他客户。用 Cypher 怎么写?
// 两度关联查询
MATCH (c:Customer {id: 'C001'})-[:USES]->(p:Phone)-[:REGISTERED_ON]->(d:Device)
MATCH (d)<-[:REGISTERED_ON]-(otherPhone:Phone)<-[:USES]-(otherCustomer:Customer)
WHERE otherCustomer.id <> 'C001'
RETURN DISTINCT otherCustomer.name, otherPhone.number
这段代码,在关系型数据库里得写多少个 JOIN?但在图数据库里,就是几行模式匹配的事。
2.3.3 批量导入
实际项目中,数据量很大,不可能一条条 CREATE。我一般用 LOAD CSV 批量导入:
// 从CSV批量导入客户
LOAD CSV WITH HEADERS FROM 'file:///customers.csv' AS row
MERGE (c:Customer {id: row.id})
SET c.name = row.name,
c.age = toInteger(row.age),
c.credit_score = toInteger(row.credit_score)
CREATE INDEX ON :Customer(id),不然几百万条数据导入,速度慢得你想哭。
2.4 本章知识体系
为了让你更直观地理解这一章的内容,我画了一张图,把 Neo4j 安装、Cypher 语法、节点关系创建串起来:
这张图把本章的三个核心模块串起来了。从左到右,先搭环境,再学语法,最后动手创建数据。每一步都是下一步的基础。
好了,这一章的内容就到这。你先把 Neo4j 装起来,跑通几个简单的 Cypher 语句,后面我们就能拿真实信贷数据来练手了。