想象你来到一个依山傍水的村子,想找一位会治跌打损伤的郎中。你不认识他,但村口王婆说:“我认识李屠户,李屠户的妹夫孙郎中正是你要找的人!”于是你沿着这条熟人链,一步步找到了目标。这就是图数据库的思维方式:把世界看作“谁认识谁”“谁关联谁”,而不是一张张孤立的表格。图数据库Neo4j用一本“村里人情簿”记录所有关联,而Cypher就是查阅这本簿子的标准问法。Cypher是一种声明式查询语言,你只需要描述“我要找什么样的关系链”,数据库自己会去匹配和遍历。本文用“人情簿”的故事贯穿始终,拆解 Cypher 的节点标签、关系方向、MATCH 模式、WHERE 过滤、变长路径与最短路径。读完你会明白,为什么社交推荐、风控反欺诈这类“关系密集型”问题,用图数据库会如此顺手。

岗位关联

掌握 Cypher,等于掌握图数据库时代最核心的查询武器——社交网络、知识图谱、风控反欺诈等场景的面试与架构设计都离不开它。

目录
  1. 可视化演示
  2. 语言概述
  3. 节点与标签
  4. 关系与方向
  5. MATCH模式
  6. WHERE过滤
  7. 路径查询
  8. 查询优化
  9. 实战场景
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

语言概述

村里有一本厚厚的“人情簿”,记录着谁和谁是熟人。如果要用一句话把“找郎中”这条线索说清楚,你会怎么说?大概是这样:“找一个王婆认识的人,他认识一位郎中。”Cypher 就是这句问话的标准语法。

Cypher 是 Neo4j 图数据库的声明式查询语言。所谓“声明式”,是指你只描述“要什么”,不描述“怎么做”。就像你跟人打听路,只说“我要找村东的郎中”,而不必交代“先走五十步再左转”。数据库引擎会在人情簿内部自动设计查找路线,替你完成遍历。

Cypher 的核心思想是图模式匹配:用一对圆括号表示节点,用方括号和箭头表示关系,把“谁认识谁”写成一种可查询的形状。对比之下,SQL 面对的是表和连接,而 Cypher 把“路径”当成一等公民,多跳关系遍历正是它的主场。

人情簿的问法一旦固定下来,后面所有复杂问题——找郎中、查账目、挖关系链——都只是这个基本句式的排列组合。学会 Cypher,本质上是学会用“关系的语言”向数据库提问。

MATCH (n) RETURN n\text{MATCH} \ (n) \ \text{RETURN} \ n
这条语句的意思是:把人情簿上的任意一个节点都匹配出来并返回,等价于“把全村人都列出来看看”。
  1. MATCH 关键字告诉查询引擎“开始按模式寻找”,它是所有查询的入口动作。
    MATCH\text{MATCH}
  2. 节点模式 (n)圆括号表示一个节点,n 是这个节点的临时名字(变量),匹配后绑定到实际数据。
    (n)(n)
  3. RETURN 返回把绑定变量 n 指向的节点作为结果输出给调用者。
    RETURN n\text{RETURN} \ n

节点与标签

人情簿上每个人的条目旁都有两个信息栏:一栏写身份,比如“猎户”“郎中”“铁匠”;另一栏写个人档案,比如“姓孙,五十岁,住西村”。在 Cypher 中,身份对应标签,档案对应属性。

一个节点的完整写法是圆括号包起来的三部分:变量名、标签、属性集。例如 (n:Person {name:'张三', age:30})。其中冒号后的 Person 是标签,用来声明这个节点属于“人”这一类别;花括号里是键值对属性,类似于人情簿里的档案字段。

标签和属性是两种不同的机制:标签用于分类和索引,相当于“这本书是中医类还是武术类”;属性用于存储具体数据,相当于书里的每一页内容。一个节点可以有多个标签,比如“郎中”和“猎人”,表示多重身份。

没有标签,人情簿就是一本天书;有了“郎中”这个标签,你就能快速锁定一类人。而属性帮你进一步判断“是不是你要找的那位”。这就是节点世界的组织方式:先分类,再细看。

(n:Person {name:′张三′, age:30})(n:\text{Person} \ \{ \text{name}: '\text{张三}', \ \text{age}: 30 \})
这句话描述了一个带标签和属性的节点:它是人,名字叫张三,年龄 30 岁。
  1. 变量名 n给节点起的临时名字,供后续子句引用,就像替别人指路时先说“这位是孙郎中”。
    nn
  2. 标签Person:冒号加标签名,声明节点类型,是图数据库建立索引和约束的根据。
    :Person:\text{Person}
  3. 属性花括号花括号内以键值对形式存储结构化字段,相当于人情簿上的档案栏。
    {name:′张三′, age:30}\{ \text{name}: '\text{张三}', \ \text{age}: 30 \}

关系与方向

王婆认识李屠户,但李屠户未必认识王婆。人情簿上的每一条熟人关系都写明了“谁指向谁”,这个指向就是方向。Cypher 用箭头表达方向,用方括号表达关系本身。

一个关系模式的完整写法是 -[r:KNOWS]->:左侧横线连着起点节点,方括号里有关系变量 r 和关系类型 KNOWS,右侧箭头指向终点节点。方向是查询语义的一部分:--> 表示从 a 到 b,<-- 表示从 b 到 a,而 -- 表示不关心方向,只要两边有连接即可。

关系也可以有自己的属性。比如 -[r:KNOWS {since:2020}]-> 记录了这段认识关系从哪一年开始。这在人情簿上就像在“认识”旁边备注了一句“三年前开始的交情”。关系属性让边不只是连接,还能承载业务语义。

有了方向,人情簿才能表达“张三关注了李四”和“李四关注张三”这两种截然不同的关系。方向不是数据存储的负担,而是查询时灵活指定的语义——一条边存下来,两个方向都能问。

(a)−[r:KNOWS]→(b)(a) - [r:\text{KNOWS}] \to (b)
这条模式表示:存在一条从节点 a 指向节点 b、类型为 KNOWS 的关系,并且把这条关系绑定到变量 r。
  1. 起点节点 (a)模式的左端,表示关系从哪里出发。
    (a)(a)
  2. 关系模式 -[rKNOWS]->:横线进入方括号,声明关系变量 r 与类型 KNOWS,再以箭头指出方向。
    −[r:KNOWS]→- [r:\text{KNOWS}] \to
  3. 终点节点 (b)模式的右端,箭头指向的节点,表示关系通向哪里。
    (b)(b)

MATCH模式

向人情簿打听消息,不能只说半句话,得把整条线索说完:“谁 → 认识谁 → 谁”。MATCH 子句就是这条完整线索的书面表达。它描述的是你想要的子图形状,而不是查找步骤。

一个典型模式由节点和关系交替串联而成。比如要找出所有“猎户认识郎中”的配对,可以写:MATCH (a:Person)-[:KNOWS]->(b:Person) WHERE a.职业='猎户' AND b.职业='郎中' RETURN a, b。数据库会在内部执行遍历,自动在整本人情簿上寻找所有符合该形状的片段。

模式中的变量会在匹配后被“绑定”到真实节点。a 可能绑定到王婆,b 可能绑定到孙郎中——取决于人情簿里实际存在哪些连接。你不用自己写循环,引擎的遍历器会像翻书一样逐页扫描,找出所有满足模式的子图。

MATCH 让人情簿“自己讲故事”:你描述形状,数据库负责在整本簿子里找出所有符合形状的片段。这就是声明式查询和命令式代码最大的区别——把“找”的动作交给引擎,把“要什么”留给自己。

MATCH (a:Person)−[:KNOWS]→(b:Person) RETURN a, b\text{MATCH} \ (a:\text{Person}) - [:\text{KNOWS}] \to (b:\text{Person}) \ \text{RETURN} \ a, \ b
找出所有由一条 KNOWS 关系连接的两个 Person 节点,并成对返回——相当于“把人情簿上所有认识关系列出来”。
  1. MATCH 开启匹配告诉引擎“现在开始根据模式找数据”。
    MATCH\text{MATCH}
  2. 节点绑定 (aPerson):匹配任意 Person 节点,并把结果记到变量 a 上。
    (a:Person)(a:\text{Person})
  3. 关系约束 -[KNOWS]->:要求从 a 到 b 存在一条 KNOWS 关系,关系类型限定了语义。
    −[:KNOWS]→- [:\text{KNOWS}] \to
  4. 终点绑定 (bPerson):匹配另一端 Person 节点并绑定到变量 b。
    (b:Person)(b:\text{Person})
  5. RETURN 输出结果把 a 和 b 两个变量对应的节点作为结果返回。
    RETURN a, b\text{RETURN} \ a, \ b

WHERE过滤

口信不能只说“找郎中”,还得补一句“找城西的孙郎中”。这句附加条件,在 Cypher 中就是 WHERE 子句。它跟在 MATCH 之后,用来收紧匹配范围。

WHERE 支持比较运算:>、<、=、<> 分别表示大于、小于、等于、不等于。比如 a.age > 30 表示只要年龄大于 30 的节点。多个条件可以用逻辑组合:AND 表示同时满足,OR 表示满足其一,NOT 表示取反。这种组合方式和人说话的习惯几乎一样——“要找三十岁以上的,并且住在东村的郎中”。

WHERE 与 MATCH 的配合是 Cypher 最常用的查询形态。MATCH 负责在结构上“找形状”,WHERE 负责在数据上“筛条件”。两者结合,就能精准定位到特定的一类人:不只是“一个认识郎中的王婆”,而是“一个认识城东孙郎中的王婆”。

人情簿里的关系链不变,WHERE 就像问话时多带的那句“只要……”。它不改变匹配的形状,只改变匹配的结果范围,让查询从“找到一群人”变成“找到特定的人”。

WHERE a.age>30 AND b.city=′北京′\text{WHERE} \ a.\text{age} > 30 \ \text{AND} \ b.\text{city} = '\text{北京}'
过滤器要求节点 a 的年龄大于 30,同时节点 b 的城市属性等于“北京”。
  1. 条件一 a.age > 30用点号取出节点 a 的 age 属性,与数字 30 比较。
    a.age>30a.\text{age} > 30
  2. 逻辑组合 AND要求左右两个条件同时成立,缺一不可。
    AND\text{AND}
  3. 条件二 b.city = '北京'取出节点 b 的 city 属性,判断是否等于字符串“北京”。
    b.city=′北京′b.\text{city} = '\text{北京}'

路径查询

有时你不知道中间隔着几个人,只想知道“从王婆到周小贩,要经过几层熟人?”这就是路径查询的用武之地。它不关心某个具体节点,而是关心节点之间的路径。

变长路径用星号和范围表达跳数:(a)-[:FRIEND*1..3]->(b) 表示寻找 a 到 b 之间 1 到 3 跳的 FRIEND 关系链。*2.. 表示至少两跳,* 表示任意跳数。这就像说“只要在几层熟人以内能找到就行”,社交软件里的“可能认识的人”就常用这种写法。

最短路径函数 shortestPath 返回两节点之间跳数最少的路径。它非常适合“最快找到联系人”的场景。路径本身也可以保存到变量中:p = shortestPath((a)-[:FRIEND*]->(b)),之后可以访问 p 的长度、节点序列等信息,像研究一条完整的熟人链。

六度分隔理论在人情簿上就是一条查询语句。变长路径解决“多少层以内有关系”的问题,最短路径解决“最快怎么搭上线”的问题。两者合起来,构成了图数据库最具辨识度的能力。

p=shortestPath((a)−[:FRIEND∗]→(b))p = \text{shortestPath}((a) - [:\text{FRIEND} \ast] \to (b))
从 a 到 b 沿着任意深度的 FRIEND 关系找到最短路径,并把整条路径存入变量 p。
  1. 路径变量 p =把计算出的路径结果赋值给变量 p,供后续使用。
    p=p =
  2. shortestPath 函数求两点之间经过关系数最少的路径。
    shortestPath(...)\text{shortestPath}(...)
  3. 任意深度关系 [\text{FRIEND}*]:星号表示不限制关系跳数,任意深度均可。
    [:FRIEND∗][:\text{FRIEND} \ast]
  4. 端点与方向 (a) → (b)路径从 a 出发,沿有向关系最终到达 b。
    (a)→(b)(a) \to (b)

查询优化

人情簿厚得搬不动时,怎么快速找到“姓孙的郎中”?有经验的人会先翻“郎中”这一类的索引页,再在那一小撮人里找姓孙的。Cypher 的优化思路完全一致:建立索引,缩小扫描范围。

在 Neo4j 中,可以针对“标签 + 属性”建立索引,例如 CREATE INDEX FOR (n:Person) ON (n.name)。这样 WHERE n.name = '张三' 就不再需要扫描全部 Person 节点,而是像查字典一样直接定位。执行计划是数据库为查询设计的内部方案,用 EXPLAIN 关键字可以预览它,用 PROFILE 可以查看实际执行的成本。

常见的查询瓶颈是变长路径深度过大。*1..5 与 *1..3 虽然只差两跳,但搜索空间可能指数级膨胀——每一跳都可能把关系数翻倍。调优策略包括:限定关系类型与方向、控制最大深度、把大图拆成小图,以及优先使用索引命中起始节点。

人情簿的索引页就像书的目录,先从目录定位一小群人,再在人堆里细找。Cypher 优化的核心思想也是“先缩小范围,再精准匹配”。面对慢查询,不要急着改业务逻辑,先看看执行计划有没有走索引。

EXPLAIN MATCH (n:Person) WHERE n.name=′张三′ RETURN n\text{EXPLAIN} \ \text{MATCH} \ (n:\text{Person}) \ \text{WHERE} \ n.\text{name} = '\text{张三}' \ \text{RETURN} \ n
这条语句不真正执行查询,而是让数据库返回它的执行计划,方便你检查是否用上了索引。
  1. EXPLAIN 关键字只生成执行计划不运行查询,用于性能分析。
    EXPLAIN\text{EXPLAIN}
  2. 约束标签 MATCH (nPerson):先锁定 Person 标签,缩小候选集合。
    (n:Person)(n:\text{Person})
  3. 索引条件 WHERE n.name = '张三'如果该属性已建索引,引擎会走索引直接命中。
    n.name=′张三′n.\text{name} = '\text{张三}'

实战场景

整本人情簿就是一个情报网。推荐“你可能认识的人”、识别“可疑的资金链”、回答“谁是项目负责人”,都靠多跳查询。图数据库真正的价值,是把藏在关系里的洞察挖出来。

社交推荐是最经典的应用。要找出“朋友的朋友”,只需写 (u)-[:FRIEND]->(f)-[:FRIEND]->(candidate),就能得到所有二度人脉——这正是 LinkedIn“你可能认识的人”背后的查询逻辑。风控反欺诈则利用多级转账路径:(a)-[:TRANSFER*1..5]->(b) 可以追踪资金如何在多个账户间流转,找出循环转账的洗钱团伙。知识图谱问答把实体之间的关系变成可查询的边,类似“谁负责了这个项目”这样的问题,在人情簿上就是一条简单的关系链。

下面这条模式是“协同过滤”的图表达:找到和你买过同一件商品的其他用户,再把他们的购买记录推荐给你。

人情簿最后成了全村人的第二大脑。无论是找人、推荐还是查风险,一句 Cypher 就能把藏在关系深处的答案挖出来——这正是图数据库在现代数据架构中不可替代的原因。

(u)−[:PURCHASE]→(Item)←[:PURCHASE]−(v)(u) - [:\text{PURCHASE}] \to (\text{Item}) \leftarrow [:\text{PURCHASE}] - (v)
这条模式表示:用户 u 买过某商品,用户 v 也买过同一商品,于是 v 可以作为 u 的推荐参考。
  1. 左端用户 (u)当前正在被推荐的用户节点。
    (u)(u)
  2. 购买关系 -[PURCHASE]->:表示 u 购买过某件商品。
    −[:PURCHASE]→- [:\text{PURCHASE}] \to
  3. 商品节点 (Item)被购买的共同物品,是连接两个用户的桥梁。
    (Item)(\text{Item})
  4. 反向购买关系 ←-[PURCHASE]-(v):表示 v 也从另一端买过同一商品,箭头指向 Item。
    ←[:PURCHASE]−(v)\leftarrow [:\text{PURCHASE}] - (v)

AI 应用场景

社交网络好友推荐

阶段:特征召回与图遍历

解决的问题:传统 SQL 实现“朋友的朋友”需要多次自连接,深度受限且语句冗长;AI 推荐系统需要快速召回大规模关系数据。Cypher 用一条变长路径查询即可完成多跳召回,再将结果交给排序模型。

具体案例:LinkedIn 的“二度人脉”功能中,用户查看某个联系人时,后端用 MATCH (u)-[:CONNECTED_TO*1..2]->(candidate) 召回潜在好友,再结合共同好友数、行业相似度等特征排序,推荐准确率显著提升。

金融风控反欺诈链路追踪

阶段:风险识别与图特征提取

解决的问题:洗钱团伙通常通过多级账户转账混淆资金流向,传统关系型数据库难以高效追踪跨三层以上的转账链路。Cypher 可以用变长路径和环检测模式,把可疑资金链完整拉出来。

具体案例:某银行风控系统将账户与转账记录建成图,用 MATCH (a)-[:TRANSFER*2..5]->(b) WHERE a.id <> b.id 检测循环转账路径。系统每周自动扫描出上百条可疑链路,交由反洗钱分析师复核,比原先的 SQL 方案快一个数量级。

企业知识图谱问答

阶段:语义解析与知识检索

解决的问题:企业内部文档分散,问答系统需要把自然语言问题翻译成结构化查询。Cypher 作为知识图谱的查询接口,能把“谁是 XX 项目的负责人”变成 MATCH (p:Person)-[:LEADS]->(proj:Project {name:'XX'}) RETURN p。

具体案例:某大型制造企业搭建了以 Neo4j 为核心的知识图谱,覆盖人员、项目、设备、供应商等实体。运维人员用自然语言提问,系统自动生成 Cypher 查询并在图谱中检索,将平均问题响应时间从查文档的 2 小时缩短到 3 秒。

Python 演示

python71 行
from collections import deque  class SocialGraph:    def __init__(self):        self.people = {}        self.relations = []        self.adj = {}     def add_person(self, name, **props):        self.people[name] = props        self.adj[name] = []        return self     def add_relation(self, a, b, rtype='KNOWS'):        self.relations.append((a, b, rtype))        self.adj[a].append(b)        self.adj[b].append(a)        return self     def match_person(self, **filters):        """模拟 MATCH (n) WHERE n.k=v RETURN n"""        result = []        for name, props in self.people.items():            if all(props.get(k) == v for k, v in filters.items()):                result.append(name)        return result     def friends_of_friends(self, name, depth=2):        """模拟变长路径 (name)-[:KNOWS*1..depth]->(x)"""        level = {name}        for _ in range(depth):            nxt = set()            for p in level:                nxt.update(self.adj[p])            level = nxt        level.discard(name)        return sorted(level)     def shortest_hop(self, a, b):        """模拟 shortestPath((a)-[:KNOWS*]->(b)) 的跳数"""        queue = deque([(a, 0)])        seen = {a}        while queue:            node, dist = queue.popleft()            if node == b:                return dist            for nei in self.adj[node]:                if nei not in seen:                    seen.add(nei)                    queue.append((nei, dist + 1))        return -1  if __name__ == '__main__':    g = SocialGraph()    g.add_person('王婆', age=58, city='东村', job='媒人')    g.add_person('李屠户', age=42, city='东村', job='屠户')    g.add_person('孙郎中', age=50, city='西村', job='郎中')    g.add_person('赵猎户', age=35, city='东村', job='猎户')    g.add_person('周小贩', age=28, city='西村', job='小贩')     g.add_relation('王婆', '李屠户')    g.add_relation('李屠户', '孙郎中')    g.add_relation('李屠户', '赵猎户')    g.add_relation('赵猎户', '周小贩')    g.add_relation('孙郎中', '周小贩')     print('东村的村民:', g.match_person(city='东村'))    print('王婆的两度熟人:', g.friends_of_friends('王婆', depth=2))    print('王婆到周小贩的最短跳数:', g.shortest_hop('王婆', '周小贩'))
目的:用对象和图遍历模拟 Cypher 的 MATCH、WHERE、变长路径与最短路径功能,帮助理解图查询背后的执行逻辑。
  1. self.adj[name] = []初始化邻接表,记录每个人直接认识的人。
  2. add_relation等价于 Cypher 的 CREATE (a)-[:KNOWS]->(b),在邻接表里双向记录。
  3. match_person(**filters)对应 WHERE n.city='东村' 这样的属性过滤。
  4. friends_of_friends(depth=2)对应变长路径 *1..2,用 BFS 逐层扩散。
  5. shortest_hop对应 shortestPath 函数,用广度优先搜索找最少跳数。

常见误区

误区我刚接触时觉得 SELECT 对应 MATCH,JOIN 对应关系箭头,WHERE 两边都有,学完 SQL 就能直接上手 Cypher,无非是换个关键字。

正解两者思维模式完全不同。SQL 是“拼表后投影字段”,Cypher 是“描述子图结构并匹配”。就像查“王婆认识谁”,SQL 要 JOIN 两张表再过滤,Cypher 直接写出 (王婆)-[认识]->(谁) 的形状,数据库自己找。模式匹配和表连接是两种世界观。

为何常见:两者都是查询语言,都有 RETURN/WHERE 等相似关键字,初学者自然会产生“换皮 SQL”的错觉。

误区我担心 `(a)-[:KNOWS]->(b)` 只存了 a 到 b 的方向,查反向就得再建一条 `(b)-[:KNOWS]->(a)`,否则数据会丢。

正解Cypher 中方向是查询时指定的语义,不是存储时的限制。用 (a)--(b) 就能匹配任意方向的关系。一条边存进去,两个方向都能问,就像人情簿上的“王婆认识李屠户”不必再抄一遍“李屠户被王婆认识”。

为何常见:关系型数据库的外键是单向的,习惯从表结构思考的人很容易把这个约束带到图世界里。

误区我觉得 `*1..10` 比 `*1..3` 更厉害,多跳几层能找到更多关系,查询结果肯定更丰富,为什么不直接写深一点?

正解变长路径的搜索空间随深度指数膨胀。深度从 3 加到 5,需要遍历的关系数量可能翻几十倍,查询时间急剧上升,还可能出现大量冗余路径。所以应该先限定关系类型和方向,再把深度控制在业务真正需要的范围内。

为何常见:“多跳几步”在直觉上只是多走点路,但图的度数相乘效应让跳数增长远比想象中快。

误区节点括号里写 `:Person` 和 `{name:'张三'}` 看起来都是描述节点的信息,所以标签就是一种特殊的属性,没必要区分。

正解标签是类型标识,决定节点属于哪个类别、享受哪些索引;属性是具体数据,描述单个节点的特征。就像“郎中”是身份分类,而“姓孙、五十岁、住西村”是个人档案。分类和档案不属于同一个层次,索引只能建立在标签+属性之上。

为何常见:两者写在同一个括号里,视觉上紧挨着,初学者容易把它们混为一谈。

误区我以为最短路径只有一个答案,就像地图导航总给出一条最优路线,函数返回的就是那条唯一的路径。

正解两点之间可能有多条跳数相同的最短路径,shortestPath 返回的是其中一条,并不保证唯一。想要全部最短路,需要用 allShortestPaths 并配合 LIMIT 控制数量。就像村里两条路都能 3 分钟到郎中家,函数只告诉你其中一条。

为何常见:日常语言里“最短路”听起来像唯一解,忽略了图结构里等长路径可以有很多条。

面试题

Q1. 在 Cypher 中,(n:Person) 的 Person 表示什么?

单选题 · easy

  • A.给节点添加一个名字属性
  • B.声明节点属于人这个类型← 正确答案
  • C.创建名为 Person 的变量
  • D.过滤名字为 Person 的记录

答案:B。冒号后的 Person 是标签,用来声明节点的类型归属,对应人情簿上“郎中”这类身份。它不是属性、不是变量,也不是过滤条件。

Q2. 关系模式 -[r:KNOWS]-> 中的箭头表示什么?

单选题 · easy

  • A.数据在磁盘上的存储方向
  • B.查询模式下关系的指向← 正确答案
  • C.关系中属性的排列顺序
  • D.节点与标签的从属关系

答案:B。箭头表示查询语义中关系的方向,从起点节点指向终点节点。它在查询时指定,而非存储时固定。就像“王婆指向李屠户”描述的是打听路径的方向。

Q3. MATCH (a)-[:FRIEND]->(b) 中的 a 和 b 是什么?

单选题 · mid

  • A.两个中间变量,用于引用匹配结果← 正确答案
  • B.两种不同的节点标签
  • C.两个关系类型的名称
  • D.两个返回给用户的列表

答案:A。a 和 b 是节点变量,匹配成功后绑定到真实节点,供 RETURN 或后续子句引用。就像指路时先说“这位是王婆”,后面才能用名字称呼她。

Q4. 关于 Cypher 的 WHERE 子句,以下说法正确的有?

多选题 · mid

  • A.能用比较符筛选节点属性← 正确答案
  • B.能用 AND 和 OR 组合多个条件← 正确答案
  • C.能直接指定返回的列数量
  • D.能用在 MATCH 模式之后过滤← 正确答案

答案:ABD。WHERE 支持 >、= 等比较运算,也支持 AND/OR/NOT 逻辑组合,并且跟在 MATCH 之后使用。它负责过滤数据,不负责控制返回列数量,那是 RETURN 和 LIMIT 的职责。

Q5. 变长路径 (a)-[:KNOWS*1..3]->(b) 表示什么?

单选题 · mid

  • A.恰好经过三跳的路径
  • B.一到三跳之间的任意路径← 正确答案
  • C.至少经过三跳的路径
  • D.至多经过一条边的路径

答案:B。*1..3 表示跳数范围从 1 到 3,即只要在这段范围内的路径都会被匹配,不是固定 3 跳。就像说“一到三层熟人以内能找到就行”。

Q6. shortestPath((a)-[:ROAD*]->(b)) 函数的作用是什么?

单选题 · mid

  • A.求两点间最短路径并返回路径← 正确答案
  • B.统计图中所有路径的数量
  • C.删除图中多余的关系边
  • D.找出没有任何关系的孤立节点

答案:A。shortestPath 计算两个节点之间关系数最少的路径并返回路径本身,常用于“最快建立联系”类查询。它不统计、不删除、不找孤立点。

Q7. 相比传统 SQL 自连接,Cypher 图查询的优势体现在哪些场景?

多选题 · hard

  • A.多跳关系遍历性能更优← 正确答案
  • B.最短路径计算免去递归代码← 正确答案
  • C.大规模数值聚合统计更快
  • D.可变深度模式适合社交推荐← 正确答案

答案:ABD。图数据库把关系作为一等公民,多跳遍历和最短路径是原生能力;变长路径让社交推荐等场景表达简洁。但纯粹的数值聚合(如 SUM/AVG 大表统计)不是图数据库的强项,SQL 更合适。

Q8. 在 Cypher 中,RETURN n 的作用是什么?

单选题 · easy

  • A.删除匹配到的所有节点
  • B.返回匹配到的节点作为结果← 正确答案
  • C.创建一份节点数据备份
  • D.更新节点的属性值

答案:B。RETURN 把匹配或计算的结果输出给调用方,类似于把人名从人情簿里“抄出来给你看”。它不删除、不备份、不更新。

Q9. 节点属性用花括号括起来,以下哪项写法正确?

单选题 · easy

  • A.正确:(n:Person {name:'张三', age:30})← 正确答案
  • B.错误:属性应放在圆括号里
  • C.错误:属性应放在方括号里
  • D.错误:属性应放在尖括号里

答案:A。Cypher 用花括号存放键值对形式的属性,写在标签之后,如 {name:'张三', age:30}。其他括号各有用途:圆括号是节点,方括号是关系。

Q10. 关于 Cypher 查询性能,以下说法正确的有?

多选题 · hard

  • A.变长路径过深会让搜索空间膨胀← 正确答案
  • B.标签加属性索引能加速匹配← 正确答案
  • C.关系方向不会影响执行计划
  • D.EXPLAIN 能预览执行计划← 正确答案

答案:ABD。变长路径深度增加会让候选路径指数增长;在标签+属性上建索引能显著缩小扫描范围;EXPLAIN 用于预览执行计划。但关系方向会影响执行计划的搜索顺序和效率,并非无关。