第二章:图数据库基础:Neo4j安装、Cypher查询语言入门、节点与关系建模

好,咱们正式开始动手了。

上一章聊了内幕交易网络的理论框架,说白了就是「谁跟谁有关系,关系是什么」。但光有理论不行,得有个地方把这些「人」和「关系」存起来、查出来。这时候,图数据库就该登场了。

我个人习惯把图数据库比作「乐高底板」。关系型数据库像Excel表格,一行一行存数据;图数据库呢,每个节点就是一块积木,关系就是积木之间的卡扣。你想想看,查内幕交易网络,最核心的就是查「A通过B认识了C,C又给D打了电话」——这种多跳查询,用SQL写出来能绕晕你,但用图数据库,几行代码搞定。

2.1 Neo4j安装:别怕,就三步

我最早接触Neo4j是在2018年,当时为了查一个跨账户对倒的案子。安装过程踩了不少坑,今天我把最稳的路径告诉你。

核心原则:生产环境用社区版(免费),别一上来就搞企业版。我见过有人花两天配置企业版集群,最后发现社区版完全够用。

2.1.1 下载与安装

去官网下载Neo4j Community Edition,目前稳定版是5.x。我建议用桌面版(Neo4j Desktop)入门,省心。

  1. 下载安装包:Windows选exe,Mac选dmg,Linux选tar.gz。
  2. 启动服务:桌面版直接点「Start」。命令行版的话,进bin目录执行 ./neo4j start
  3. 验证:浏览器打开 http://localhost:7474,看到Neo4j Browser界面就算成了。

小技巧:我第一次装的时候,死活连不上7474端口。后来发现是Java版本不对。Neo4j 5.x需要JDK 17以上。你可以在终端敲 java -version 确认一下。

2.1.2 避坑指南

我曾经遇到过一个问题:Neo4j启动后,浏览器访问显示「Connection refused」。排查了半天,发现是防火墙把7474端口封了。Windows用户记得去防火墙设置里放行一下。

另外,内存配置别贪多。默认堆内存512M够用了。你非要调成4G,反而可能因为GC停顿导致查询变慢。

2.2 Cypher查询语言入门:像说话一样查数据

Cypher是Neo4j的查询语言。我第一次看到它的时候,第一反应是「这玩意儿也太像自然语言了吧?」

举个例子:你想查「张三给李四打了电话」,在SQL里你得写JOIN,在Cypher里呢?

MATCH (a:Person {name: '张三'})-[r:打电话]->(b:Person {name: '李四'})
RETURN a, r, b

你看,MATCH就是「匹配」,(a:Person)是节点,-[r:打电话]->是关系。读起来就是「匹配一个人叫张三,他打电话给另一个人叫李四,返回他们俩和电话记录」。

是不是很直观?

2.2.1 核心语法速览

操作 Cypher写法 说明
创建节点 CREATE (n:Person {name: '张三'}) 创建一个标签为Person、属性name为张三的节点
创建关系 CREATE (a)-[r:认识]->(b) 在a和b之间创建一条「认识」关系
查询节点 MATCH (n:Person) RETURN n 查询所有Person标签的节点
查询关系 MATCH (a)-[r]->(b) RETURN a, r, b 查询所有关系及其两端节点
条件过滤 WHERE n.age > 30 筛选年龄大于30的节点
删除节点 DETACH DELETE n 删除节点及其所有关系

重点:在反欺诈场景里,最常用的是 MATCH...WHERE...RETURN 组合。比如查「所有给张三打过电话、且通话时长超过5分钟的人」:

MATCH (a:Person)-[r:打电话]->(b:Person {name: '张三'})
WHERE r.时长 > 300
RETURN a, r

2.2.2 多跳查询:图数据库的杀手锏

内幕交易网络最怕什么?怕「间接关联」。A和C没有直接联系,但A认识B,B认识C。这种多跳关系,在关系型数据库里查起来非常痛苦,但在Cypher里,一行搞定。

MATCH (a:Person {name: '张三'})-[:认识*1..3]->(c:Person)
RETURN a, c

这个 [:认识*1..3] 的意思是「沿着认识关系,走1到3步」。也就是说,查所有张三直接认识的人、朋友的朋友、以及朋友的朋友的朋友。

嗯,这里要注意:跳数别设太大。我见过有人设 *1..10,结果查询跑了5分钟没出来。图数据库虽然擅长多跳,但跳数太多,中间节点呈指数级增长,性能扛不住。一般反欺诈场景,3到4跳就够用了。

2.3 节点与关系建模:把现实世界「翻译」成图

这是整个课程里最核心的部分。模型建得好,后面分析就顺;模型建得烂,后面全是坑。

我自己的经验是:建模之前,先画一张草图。拿内幕交易来说,你想想看,现实世界里有哪些「实体」和「关系」?

2.3.1 实体(节点)设计

常见的实体有:

  • 人(Person):内幕交易的核心参与者。属性包括姓名、身份证号、手机号、邮箱、职业等。
  • 公司(Company):被交易的标的。属性包括公司名称、股票代码、行业等。
  • 账户(Account):交易发生的载体。属性包括账户号、开户行、交易时间等。
  • 设备(Device):操作交易的终端。属性包括设备ID、IP地址、MAC地址等。

我个人习惯:给每个节点加一个 id 属性作为唯一标识,别依赖Neo4j自带的内部ID。内部ID在数据迁移时会变,容易出问题。

2.3.2 关系(边)设计

关系是图数据库的灵魂。内幕交易里,常见的关系有:

关系类型 示例 属性
认识 张三 -[认识]-> 李四 认识时间、关系亲密度
通话 张三 -[打电话]-> 李四 通话时间、时长、频次
交易 张三 -[买入]-> 某公司股票 交易时间、金额、数量
设备关联 张三 -[使用]-> 某设备 首次使用时间、使用频次

2.3.3 建模实战:一个内幕交易小案例

假设我们有这么个场景:张三和李四是大学同学,张三在某上市公司当高管,李四是个散户。张三在公布财报前,给李四打了个电话。李四随后用自己账户买入了该公司股票。

用图模型怎么表示?

// 创建节点
CREATE (zs:Person {name: '张三', 职业: '高管', 公司: 'XX科技'})
CREATE (ls:Person {name: '李四', 职业: '散户'})
CREATE (comp:Company {name: 'XX科技', 股票代码: '000001'})
CREATE (acc:Account {账户号: '622202****1234', 开户行: '工商银行'})

// 创建关系
CREATE (zs)-[:认识 {时间: '2019-01-01', 关系: '大学同学'}]->(ls)
CREATE (zs)-[:任职于]->(comp)
CREATE (ls)-[:使用]->(acc)
CREATE (ls)-[:买入 {时间: '2019-03-15', 金额: 500000, 数量: 10000}]->(comp)

你看,这个模型把「人-人-公司-账户」串起来了。后面查的时候,只要沿着关系走,就能发现异常模式。

我曾经犯过一个错误:把所有关系都设计成无向的。比如「认识」关系,我用了 [:认识] 而不是 [:认识]->。结果查方向性关系(比如「谁给谁打电话」)时,数据全乱了。记住:关系一定要有方向,哪怕语义上是双向的,也建议用有向边表示。

2.4 本章知识体系总览

下面这张图,是我自己画的,把本章的核心逻辑串起来了。你一看就明白:

第二章:图数据库基础 - 知识体系 Neo4j安装 下载 → 启动 → 验证 避坑:Java版本、端口 Cypher查询语言 CREATE / MATCH / WHERE 多跳查询:*1..3 节点与关系建模 实体:人/公司/账户/设备 关系:认识/通话/交易 核心逻辑:安装环境 → 学习查询 → 设计模型 三者缺一不可,模型设计决定后续分析效率

这张图把本章的三个模块串起来了:先装好Neo4j,再学会Cypher,最后设计出合理的图模型。顺序别搞反,我见过有人先建模再学Cypher,结果发现语法不支持,又回头改模型,浪费时间。

总结一下:

  • Neo4j安装不难,注意Java版本和端口就行。
  • Cypher语法像说话,多跳查询是核心优势。
  • 建模时,实体和关系要分开设计,关系一定要有方向。

下一章,咱们就用这些知识,开始构建第一个内幕交易网络图谱。到时候我会拿一个真实脱敏的案例,带你们一步步走通全流程。

专注资料整理