第二章 图数据库入门: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 没开。

小提示: 生产环境别用默认密码。我曾经见过一个信贷系统,Neo4j 密码还是 neo4j/neo4j,数据直接裸奔,想想都后怕。

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 差不多,但更直观。

核心概念: Cypher 的匹配模式就是「画图」。你脑子里怎么画关系图,代码就怎么写。这是它最大的优势。

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安装与配置 Docker部署 / 本地安装 端口映射:7474 / 7687 浏览器验证连接 Cypher查询语言 MATCH / CREATE / MERGE 节点() / 关系[] / 方向-> 属性查询与过滤 节点与关系创建 客户 / 手机号 / 设备 USES / REGISTERED_ON LOAD CSV批量导入 核心目标:搭建图数据库环境,掌握Cypher基本操作

这张图把本章的三个核心模块串起来了。从左到右,先搭环境,再学语法,最后动手创建数据。每一步都是下一步的基础。

好了,这一章的内容就到这。你先把 Neo4j 装起来,跑通几个简单的 Cypher 语句,后面我们就能拿真实信贷数据来练手了。


专注资料整理