4. Cypher 查询语言基础归纳总结
说起 Cypher,这玩意看着像 SQL,但本质完全不同。SQL 问的是“有哪些人买了什么”,Cypher 问的是“这个人和那个人的关系链有多长”。在反欺诈图谱里,我们关心的就是这种“谁跟谁、通过什么、做了什么”的链接关系。
我刚开始从 SQL 转过来时,差点被它的语法逼疯。脑子里全是 JOIN ON,突然换成 -[:某种关系]->,怎么看怎么别扭。但跑通一个 5 层担保链查询后,我就回不去了。真的快。
下面我把 Cypher 最核心的四个知识点拆开来讲。这些都是我在实际反欺诈场景里每天都要用的东西。
4.1 节点与标签:图谱里的“谁”
节点就是实体。一个人、一张银行卡、一台设备、一个手机号,在 Neo4j 里都叫节点。每个节点可以挂一个或多个标签(Label),标签的作用跟 SQL 里的表名差不多——用来分类。
核心记忆点:
- 节点用小括号
( )表示,里面写变量名和标签。 - 标签前面要加英文冒号
:。 - 变量名只在当前查询生效,用来后续引用。
| 概念 | 写法示例 | 含义 |
|---|---|---|
| 无标签节点 | (n) |
临时变量 n,不限制类型 |
| 单标签节点 | (p:Person) |
p 是 Person 类型的节点 |
| 多标签节点 | (d:Device:Mobile) |
d 同时是设备和手机 |
| 带属性节点 | (p:Person {id:'P1001'}) |
p 的 id 属性等于 'P1001' |
我的个人习惯:变量名尽量短,比如 p 代表人、a 代表账号、d 代表设备。反欺诈查询经常要链式写,短变量名能少打很多字,也不容易看花眼。
4.2 关系与方向:图谱里的“怎么连”
关系是 Cypher 的灵魂。没有关系,节点只是一堆孤立的记录。关系用 -[ ]-> 表示,方向箭头必须明确。
在我做过的反欺诈项目里,最常见的几种关系:
[:LOGIN]— 登录了哪个设备[:TRANSFER_TO]— 转账给了谁[:BIND]— 绑定了哪个手机号[:IS_SAME]— 属于同一团伙
我曾经踩过的坑:关系必须要有方向,但查询时可以忽略方向。我在一个担保链查询里忘了加方向符号,结果 Neo4j 把两边的数据都扫出来了,多跑了 3 倍的数据量。如果你只查单向,记得加上 -> 或 <-。
关系也能挂属性。比如转账金额、时间戳、IP 地址——这些在反欺诈里都是关键特征。
// 创建一条带属性的关系
CREATE (p1:Person {name:'张三'})-[r:TRANSFER_TO {amount:5000, time:'2024-01-15 13:22:10'}]->(p2:Person {name:'李四'})
4.3 模式匹配:怎么写查询
Cypher 的核心操作就是“匹配一个子图模式”。说白了,你把你想找的结构画出来,Cypher 去图里找一模一样的。
最常见的三种模式:
- 节点 ← 关系 → 节点:我查张三转账给谁了。
- 节点 - 关系 - 节点:我查两个设备有没有共用同一个账号。
- 节点:单纯查某个标签下的所有节点。
必记住句模式:
MATCH (a:Person {id:'P1001'})-[r:LOGIN]->(d:Device)
WHERE r.time > datetime('2024-01-01')
RETURN a, r, d
MATCH 是找图模式,WHERE 是过滤,RETURN 是输出。这个三段式撑起了 80% 的反欺诈查询。
4.4 聚合与路径:批量出特征
单个节点或关系是信息,多个节点聚合在一起才是变量。反欺诈里最常用的聚合就是计数和去重。
| 聚合函数 | 用途 | 反欺诈示例 |
|---|---|---|
COUNT() |
统计条数 | 该设备登录过多少个不同账号 |
DISTINCT |
去重计数 | 该 IP 关联了多少个不同手机号 |
SUM() |
求和 | 一笔交易流经的总金额 |
COLLECT() |
收集成列表 | 收集该节点的所有关联手机号 |
路径也是变量生成的法宝。通过 shortestPath 或变长路径 [*1..5],我们能找出两个实体之间的连通深度。深度越短,关系越紧密,在反欺诈里往往意味着风险越高。
// 查张三和李四之间最短关系路径(不超过 5 层)
MATCH p = shortestPath(
(a:Person {name:'张三'})-[*1..5]-(b:Person {name:'李四'})
)
RETURN length(p) AS 距离, nodes(p) AS 路径节点
4.5 CREATE 与 MERGE:写数据也要注意
日常反欺诈里,读数据多,写数据少。但一旦需要写,就要格外小心。我见过太多人把 CREATE 当成 MERGE 用,结果插入了大量重复节点。
核心区别:
CREATE— 无条件新建,不会检查是否已存在。用来创建日志类数据,比如每次登录都新写一条关系。MERGE— 先找,找不到才创建。用来写实体节点,比如用户 ID、设备指纹。
举个例子:如果你每天跑批,把当天交易的手机号和设备绑定关系写进图里,用 MERGE 能防重复。但如果你记录每次登录事件的 LOGIN 关系,反而用 CREATE,因为同一个人可以多次登录,每次都是新的记录。
// 创建实体用 MERGE
MERGE (d:Device {fingerprint:'ABC123'})
ON CREATE SET d.first_seen = datetime()
// 创建日志用 CREATE
CREATE (p:Person {id:'P1001'})-[r:LOGIN {time: datetime()}]->(d)
我的避坑指南:只要写数据,你就在修改图。生产环境里先用 MATCH 跑一遍看结果数量对不对,再改成 MERGE 或 CREATE。我吃过两次亏:一次直接把 10 万条重复节点塞进了图库,花了两小时清理。
最后,放一张 Cypher 核心要素关系图,帮你把这些概念连起来看。
以上这些,就是 Cypher 的四大基本要素:节点、关系、匹配、聚合。把这四个基础练熟,后面衍生的图特征怎么复杂都能拆解清楚。
记住一点:Cypher 的核心不是语法,而是“图思维”。你不再需要写一堆 JOIN,而是直接画结构。越画,变量生成越快。