跳到主要内容

Cypher 基础

Cypher 是 Neo4j 的声明式查询语言,专为图数据操作而设计。它的语法直观易懂,类似于自然语言,让复杂的关系查询变得简单。

Cypher 概述

Cypher 使用 ASCII 艺术风格的模式来表示图结构:

  • () 表示节点
  • --> 表示有向关系
  • [] 表示关系的详细信息
-- 查询模式:张三的朋友
MATCH (zhangsan:Person {name: '张三'})-[:FRIEND]->(friend)
RETURN friend

创建数据(CREATE)

创建节点

-- 创建单个节点
CREATE (p:Person {name: '张三', age: 30})

-- 创建多个节点
CREATE (a:Person {name: '李四', age: 28})
CREATE (b:Person {name: '王五', age: 32})

-- 创建带有多个标签的节点
CREATE (n:Person:Employee {name: '赵六', department: '技术部'})

创建关系

-- 创建节点并建立关系
CREATE (zhangsan:Person {name: '张三'})-[:FRIEND {since: '2020-01-01'}]->(lisi:Person {name: '李四'})

-- 为已存在的节点创建关系
MATCH (a:Person {name: '张三'}), (b:Person {name: '王五'})
CREATE (a)-[:COLLEAGUE {department: '技术部'}]->(b)

MERGE 语句

MERGE 会检查数据是否存在,不存在则创建,存在则返回已有数据:

-- 如果节点不存在则创建
MERGE (p:Person {name: '张三'})
ON CREATE SET p.created = datetime()
ON MATCH SET p.lastSeen = datetime()
RETURN p

-- 确保关系存在
MATCH (a:Person {name: '张三'}), (b:Person {name: '李四'})
MERGE (a)-[r:FRIEND]->(b)
ON CREATE SET r.since = date()
RETURN r

查询数据(MATCH)

基本查询

-- 查询所有节点
MATCH (n)
RETURN n

-- 查询特定标签的节点
MATCH (p:Person)
RETURN p

-- 查询带有特定属性的节点
MATCH (p:Person {name: '张三'})
RETURN p

-- 查询特定属性(使用 WHERE)
MATCH (p:Person)
WHERE p.age > 25
RETURN p.name, p.age

查询关系

-- 查询所有关系
MATCH ()-[r]->()
RETURN r

-- 查询特定类型的关系
MATCH ()-[r:FRIEND]->()
RETURN r

-- 查询节点的关系
MATCH (p:Person {name: '张三'})-[r]->(other)
RETURN type(r), other.name

-- 查询双向关系(不指定方向)
MATCH (p:Person {name: '张三'})-[r]-(other)
RETURN type(r), other.name

多跳查询

-- 查询朋友的朋友(2跳)
MATCH (p:Person {name: '张三'})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN fof.name

-- 查询可变深度的关系
MATCH (p:Person {name: '张三'})-[:FRIEND*2..4]->(fof)
RETURN fof.name

-- 查询最短路径
MATCH path = shortestPath(
(a:Person {name: '张三'})-[:FRIEND*]-(b:Person {name: '王五'})
)
RETURN path

更新数据(SET)

更新属性

-- 更新单个属性
MATCH (p:Person {name: '张三'})
SET p.age = 31
RETURN p

-- 更新多个属性
MATCH (p:Person {name: '张三'})
SET p.age = 31, p.city = '上海'
RETURN p

-- 添加新属性
MATCH (p:Person {name: '张三'})
SET p.email = '[email protected]'
RETURN p

删除属性

-- 删除单个属性
MATCH (p:Person {name: '张三'})
REMOVE p.email
RETURN p

-- 删除多个属性
MATCH (p:Person {name: '张三'})
REMOVE p.age, p.city
RETURN p

添加/删除标签

-- 添加标签
MATCH (p:Person {name: '张三'})
SET p:Employee:Manager
RETURN p

-- 删除标签
MATCH (p:Person {name: '张三'})
REMOVE p:Manager
RETURN p

删除数据(DELETE)

-- 删除关系
MATCH ()-[r:FRIEND]->()
WHERE r.since < date('2020-01-01')
DELETE r

-- 删除节点(必须先删除关系)
MATCH (p:Person {name: '张三'})-[r]-()
DELETE r
WITH p
DELETE p

-- 级联删除(删除节点及其所有关系)
MATCH (p:Person {name: '张三'})
DETACH DELETE p

条件过滤(WHERE)

-- 比较运算符
MATCH (p:Person)
WHERE p.age > 25 AND p.age < 35
RETURN p.name

-- 字符串匹配
MATCH (p:Person)
WHERE p.name STARTS WITH '张'
RETURN p.name

MATCH (p:Person)
WHERE p.name CONTAINS '三'
RETURN p.name

-- 正则表达式
MATCH (p:Person)
WHERE p.name =~ '张.*'
RETURN p.name

-- IN 运算符
MATCH (p:Person)
WHERE p.name IN ['张三', '李四', '王五']
RETURN p.name

-- 检查属性是否存在
MATCH (p:Person)
WHERE p.email IS NOT NULL
RETURN p.name

-- 检查列表
MATCH (p:Person)
WHERE '技术部' IN p.departments
RETURN p.name

结果处理

排序(ORDER BY)

-- 升序排序
MATCH (p:Person)
RETURN p.name, p.age
ORDER BY p.age

-- 降序排序
MATCH (p:Person)
RETURN p.name, p.age
ORDER BY p.age DESC

-- 多字段排序
MATCH (p:Person)
RETURN p.name, p.age, p.city
ORDER BY p.city, p.age DESC

分页(SKIP / LIMIT)

-- 限制返回数量
MATCH (p:Person)
RETURN p.name
LIMIT 10

-- 跳过前 N 条
MATCH (p:Person)
RETURN p.name
SKIP 10
LIMIT 10

-- 分页查询(第 3 页,每页 10 条)
MATCH (p:Person)
RETURN p.name
ORDER BY p.name
SKIP 20
LIMIT 10

去重(DISTINCT)

-- 去除重复结果
MATCH (p:Person)-[:FRIEND]->(friend)
RETURN DISTINCT friend.city

综合示例

社交网络场景

-- 创建示例数据
CREATE (zhangsan:Person {name: '张三', age: 30, city: '北京'})
CREATE (lisi:Person {name: '李四', age: 28, city: '上海'})
CREATE (wangwu:Person {name: '王五', age: 32, city: '北京'})
CREATE (zhaoliu:Person {name: '赵六', age: 25, city: '广州'})

CREATE (zhangsan)-[:FRIEND {since: date('2020-01-15')}]->(lisi)
CREATE (lisi)-[:FRIEND {since: date('2019-06-20')}]->(wangwu)
CREATE (wangwu)-[:FRIEND {since: date('2021-03-10')}]->(zhaoliu)
CREATE (zhangsan)-[:COLLEAGUE]->(wangwu)

-- 查询张三的所有朋友
MATCH (zhangsan:Person {name: '张三'})-[:FRIEND]-(friend)
RETURN friend.name, friend.age

-- 查询张三的朋友的朋友(推荐好友)
MATCH (zhangsan:Person {name: '张三'})-[:FRIEND]->()-[:FRIEND]->(potential)
WHERE NOT (zhangsan)-[:FRIEND]-(potential)
RETURN potential.name, potential.city

-- 统计每个城市的人数
MATCH (p:Person)
RETURN p.city, count(p) AS count
ORDER BY count DESC

-- 查询最年轻的朋友
MATCH (zhangsan:Person {name: '张三'})-[:FRIEND]-(friend)
RETURN friend.name, friend.age
ORDER BY friend.age
LIMIT 1

最佳实践

  1. 使用参数化查询:避免 SQL 注入,提高性能

    MATCH (p:Person {name: $name})
    RETURN p
  2. 合理使用索引:为经常查询的属性创建索引

    CREATE INDEX person_name FOR (p:Person) ON (p.name)
  3. 限制返回数量:避免查询大量数据

    MATCH (p:Person)
    RETURN p
    LIMIT 100
  4. 使用 EXPLAIN 分析查询:了解查询执行计划

    EXPLAIN MATCH (p:Person {name: '张三'})-[:FRIEND*5]->()
    RETURN p

下一步

掌握了基础 CRUD 操作后,继续学习 高级查询,了解聚合函数、路径查找等高级功能。