# 一、Cypher 是什么

Cypher 是操作图数据库(Neo4j)的查询语言。

图数据库里的数据不是表格(像 MySQL 的表),而是“点和线”的结构:

  • 有很多“点”(比如“人”“病”“药”),这些“点”叫节点(Node)
  • 点和点之间有“线”连接(比如“人患病”“药治人”),这些“线”叫关系(Relationship)

Cypher 的作用就是:描述“点和线”的模式,让数据库找到你要的数据。


# 二、节点(Node)怎么表示

节点是图里的“实体”(比如“张三”“感冒”),写法是:

(变量名:标签 {属性})

拆解每个部分:

  • ():必须用圆括号把节点包起来
  • 变量名:给节点起个临时名字(比如用 p 代表“人”,d 代表“病”),方便后面引用
  • :标签:节点的类别(比如 :Person 表示“人”,:Disease 表示“疾病”)。一个节点可以有多个标签(比如 :Person:Patient
  • {属性}:描述节点特征的键值对(比如 name: "张三"age: 30

例子:

// 一个“人”节点:变量 p,标签 Person,属性 name 和 age
(p:Person {name: "张三", age: 30})

// 一个“疾病”节点:变量 d,标签 Disease,属性 name
(d:Disease {name: "感冒"})

可以理解为:(p:Person {name: "张三"}) 表示“有个叫 p 的节点,它是 Person,名字叫张三”。


# 三、关系(Relationship)怎么表示

关系是节点之间的“连接”(比如“张三患感冒”),写法是:

-[变量名:类型 {属性}]->

拆解每个部分:

  • -[ ]-:中括号代表“这是一个关系”,横线连接两个节点
  • ->:箭头表示方向(比如 A->B 表示 A 到 B 的关系;无方向可以写成 --
  • 变量名:给关系起个临时名字(比如 r),方便引用
  • :类型:关系的类别(比如 :患 表示“患病”,:治疗 表示“治疗”)。每个关系只能有一个类型
  • {属性}:描述关系特征的键值对(比如 时间: "2023-10-01"

例子:

// “张三患感冒”:p(张三)通过 r(患)指向 d(感冒)
(p:Person {name: "张三"})-[r: {时间: "2023-10-01"}]->(d:Disease {name: "感冒"})

# 四、核心操作:查数据(MATCH + RETURN)

最常用的操作是“找数据”:

  • MATCH 描述要找的“点和线的模式”
  • RETURN 返回结果

# 1. 只查节点

找所有叫“张三”的人:

MATCH (p:Person {name: "张三"})
RETURN p

找所有年龄大于 30 的人,只返回名字:

MATCH (p:Person)
WHERE p.age > 30
RETURN p.name

# 2. 查关系(节点 + 关系)

找“感冒”这种病有哪些伴随的症状:

MATCH (d:Disease {name: "感冒"})-[r:伴随症状]->(s:Symptom)
RETURN d.name, r.degree, s.name

# 3. 查路径(多个关系连起来)

找“张三患的病有哪些症状”(路径:人 → 患 → 病 → 伴随 → 症状):

MATCH (p:Person {name: "张三"})-[r1:]->(d:Disease)-[r2:伴随]->(s:Symptom)
RETURN p.name, d.name, s.name

# 五、常用操作:增删改

# 1. 创建(CREATE)

新增一个叫“李四”的人,年龄 25:

CREATE (:Person {name: "李四", age: 25})

给“李四”和“感冒”加一个“患”的关系,时间是今天:

MATCH (p:Person {name: "李四"}), (d:Disease {name: "感冒"})
CREATE (p)-[: {时间: "2023-10-02"}]->(d)

# 2. 修改(SET)

把“张三”的年龄改为 31,并加上性别“男”:

MATCH (p:Person {name: "张三"})
SET p.age = 31, p.gender = "男"

# 3. 删除(DELETE / DETACH DELETE)

删除节点前,必须先删除它的所有关系;常用 DETACH DELETE 一次性删除关系和节点:

MATCH (s:Symptom {name: "发烧"})
DETACH DELETE s