想象一下这样的场景:你是一名侦探,接手了一起复杂的案件。案件材料堆满了桌子——每个人的姓名、照片、通话记录、银行转账、社交关系,散落成一团乱麻。传统的做法是把这些信息录入 Excel 表格,一行一行地查;但真正的高手会拿出一块巨大的线索板,把每个人写成一张卡片,用不同颜色的线把“谁认识谁”“谁给谁转账”“谁和谁在同一时间出现在同一地点”连起来,然后退后一步,用眼睛在整张关系网中寻找隐藏的模式。 图数据库就是那块线索板,而 Cypher 就是你在线索板上“画出问题”的方式。它不关心“第几行第几列”,只关心“谁和谁之间有什么关系”。Cypher 的迷人之处在于:你不需要告诉计算机“怎么找”(遍历步骤),只需要告诉它“找什么”(最终目标)——就像你指着线索板说:“把所有认识张三、并且给李四转过账的人找出来”,剩下的交给数据库就行。 这篇指南将带你从零开始掌握 Cypher,理解它如何通过“画模式”而非“写步骤”来查询数据,并与 SQL、Gremlin 等语言对比,让你真正理解图查询的思维方式。
图数据库是未来数据关系的核心基础设施,掌握 Cypher 意味着你拥有了直接“看见”数据关系的能力,这是传统关系型数据库思维无法替代的竞争优势。无论你是后端工程师、数据分析师还是 AI 应用开发者,这都是必备技能。
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
语法设计理念
侦探的顿悟:当你第一次站到线索板前,你会发现一个奇妙的现象——你不需要告诉助手“先把张三的卡片拿下来,再看他的通话记录,从中找出李四的号码……”你只需要说一句话:“查一下张三和李四之间有什么联系。”助手就会自己规划路线去查。这就是声明式查询:你描述目标,不描述步骤。
Cypher 的设计哲学正是如此。传统编程(命令式)像你给导航员一步步指路:“下一个路口左转,然后直行两百米,再右转……”而 Cypher(声明式)像你直接掏出地址说:“我要到这个人的家。”导航员自己选最快路线。数据库本身就是一个经验丰富的导航员,它知道哪条索引最快、哪个遍历顺序最优。
这种设计带来了三个显著特点:第一,语法可视化——Cypher 用 (节点)-[关系]->(节点) 这种类似图画的语法,让你看到查询语句就像看到一张微型线索板;第二,人类直觉驱动——你不需要成为数据库调优专家,只需要理解关系,就能写出高效的查询;第三,优化器兜底——数据库引擎会在后台把声明式语句翻译成具体的遍历步骤,正如同一个经验丰富的侦探自动规划调查路径。
回到线索板的比喻:Cypher 让你从“指挥员”变成“委托人”——你只需描述要找的关联模式,数据库这位经验丰富的老侦探会自动规划出最高效的调查路线,这正是它优雅的核心。从下一节开始,我们将具体学习如何在“线索板”上画出你的第一个查询模式。
- 声明目标你描述想要的结果模式,不描述算法步骤
- 引擎优化数据库自动决定索引选择、遍历顺序、连接策略
节点与关系模式
线索板上的基本元素:仔细看那块线索板——人物照片和线索卡片就是“节点”,连接卡片的线就是“关系”。在 Cypher 中,你要做的第一件事就是用圆括号 () 画节点,用方括号和箭头 -[关系]-> 画关系。这就像拿起笔,在空的线索板上画出第一笔草图。
Cypher 的节点语法非常直观。一个最简单的节点就是 () ——一对空括号。给它起个名字方便后续引用:(p) 就像在卡片上写个编号。如果要限定类型,用冒号:(person) 就像在卡片上盖一个“人员”红章。如果还要带上属性,用花括号:(p {name: '张三'}) 就是在卡片上再贴上姓名标签。
关系的语法是 Cypher 最迷人的地方。用 -[r]-> 表示一条有方向的线,-[:认识]-> 给线贴上类型标签。关系也可以有属性,比如从“张三”到“李四”的关系可以写成:
属性映射:再进一步,节点和关系都可以携带属性(键值对)。这就像线索卡片背后写的详细备注。用 {name: '张三', age: 35} 这种映射结构。完整的模式就变成了 (p1:Person {name:'张三'}) -[r:KNOWS {since: 2018}]-> (p2:Person)——一张详细标注的线索卡片,通过一条标注了时间的关系线,连接到另一张卡片。
回到侦探办案的场景:你现在已经学会了在线索板上画卡片、连关系线、写备注。这看似简单的“画圈连线”技能,正是 Cypher 最强大的武器——你能把脑海中的关联问题,直接转化为数据库看得懂的“图画”。
- 节点括号
(p1:Person)——一个用圆括号包起来的节点,p1 是变量名,Person 是标签 - 关系箭头
-[r:KNOWS]->——方括号里放关系变量 r 和类型 KNOWS,箭头表示方向 - 方向语义
->表示从左节点指向右节点,这是图数据库的核心——关系有方向
WHERE过滤
筛选可疑线索:线索板上的卡片越来越多,几十个人物关系纠缠在一起,满墙都是线。作为侦探,你不可能同时关注所有人——你需要一个快速筛选的办法:只要“案发当晚在咖啡店出现过的人”,且排除“与受害人直系亲属”的关系。Cypher 的 WHERE 从句正是这个“线索筛选器”。
WHERE 的作用是在 MATCH 找到的所有候选模式中,筛掉不符合条件的部分。这就像从一堆嫌疑人的卡片中,先按条件过滤:只保留年龄大于 30 岁的(WHERE p.age > 30),或者只保留在上海活动的人(WHERE p.city = '上海')。
还可以组合多个逻辑条件。使用 AND、OR、NOT 像侦探用多个维度交叉验证:年龄 > 30 且城市 = 上海(AND);要么有前科,要么出现在现场(OR);排除内部人员(NOT)。也可以用 IN 检查属性是否在某个集合中,比如 WHERE p.status IN ['嫌疑人', '证人']。
1. 属性条件:p.age > 30——节点的属性与字面量比较,如同 “年龄大于30的卡片”
2. 逻辑组合:AND/OR/NOT—— 多个条件的逻辑组合,如同用多个筛子叠加
3. 集合判断:IN—— 判断属性值是否在给定集合中,如同检查卡片是否属于某个分组
回到线索板旁,WHERE 就像你手中的马克笔——在密密麻麻的关系网中,把不满足条件的卡片划掉,留下清晰的嫌疑人名单。这个“筛选”动作贯穿所有图查询,是整个 Cypher 语法中最常用、也最需要精通的工具。
MATCH (p:Person)WHERE p.age > 30 AND p.city = '上海'RETURN p.name
聚合与排序
线索统计报告:经过初步筛选,你留下了十张嫌疑人卡片。现在你要回答的问题是:“哪个嫌疑人关联度最高?”“案发当晚每个地点出现过多少人?”这正是聚合与排序的用武之地——把零散的线索,汇集成统计报告。
Cypher 提供了丰富的聚合函数,类似于 SQL 中的 GROUP BY。COUNT(*) 统计行数,COUNT(DISTINCT p.name) 统计去重后的数量。SUM(p.amount) 做求和,AVG(p.age) 求平均。最常用的是 COUNT() 结合 GROUP BY——按照某个维度分组,然后对组内计数。比如统计每个城市的嫌疑人数:
在 Cypher 中,聚合不需要显式写 GROUP BY——你用 RETURN 直接返回分组键和聚合函数,引擎自动按非聚合字段分组。
这个查询模式在日常工作中非常常见:基于关系网络的聚合统计,在社交分析的“找出影响力最大的人”、风控中的“筛查高频交易账号”、推荐系统中的“统计热门标签”等任务中得到广泛应用。回到侦探的比喻——聚合与排序给予了你一双“统计之眼”,让你在散乱的线索中看清数字背后的格局。
- 分组键
p.city AS city——按城市分组,RETURN 中非聚合的字段自动成为分组键 - 聚合统计
COUNT(*) AS cnt——统计每组数量,如同按城市归档线索卡片 - 排序输出
ORDER BY cnt DESC——按数量降序排列,如同给嫌疑人按风险等级排序
MATCH (p:Person)RETURN p.city AS city, COUNT(*) AS cntORDER BY cnt DESC
路径查询
关系链条追踪:案件的进展总是沿着关系链推进。A 认识 B,B 转账给 C,C 是 D 的室友……在某个恰到好处的步数之内,链条会自然闭合,找到你想要的关联。这就是路径查询——探索节点之间如何通过一步步的关系彼此连通。
路径查询的核心工具是可变长度关系。你不需要写死“三步以内”或者“恰好两步”,只需要用星号(*)表示“任意长度”:
这个表达式表示:从 p1 出发,沿 KNOWS 关系走 1 到 3 步能到达的所有 p2。可能是直接认识(1步),可能是朋友的朋友(2步),也可能是三度人脉(3步)。在 Cypher 中,*1..3 是可变长度关系的标准写法。
还有一个重要功能是最短路径。shortestPath() 函数返回两个节点之间的最短路径——这是社交网络中“六度分隔”理论的计算基础,也是寻路问题(如同 GPS 导航)在关系网络中的直接应用:
路径查询是图数据库最独特的武器——关系型数据库很难高效回答“A 和 B 之间最短几步”这类问题。就像侦探追踪一条隐秘的资金链条,路径查询让这种“顺藤摸瓜”的分析从笨拙的多表自连接中解放出来,成为一行优雅的模式。
- 可变长度
-[r:KNOWS*1..3]->— 匹配 1 到 3 次 KNOWS 关系,如同侦查 1 到 3 层关系链 - 最短路径
shortestPath((a)-[:KNOWS*..6]-(b))— 在最多 6 步之内找最短连接,如同在关系网中找最直接的人脉 - 路径命名
MATCH p = ...— 把路径存到变量 p 中,如同把整条线索链用照片拍下来供后续分析
MATCH p = shortestPath( (a:Person {name:'张三'}) -[:KNOWS*..6]- (b:Person {name:'周八'}))RETURN p
SQL对比
两种查询哲学的碰撞:当团队里有人质疑“为什么不用 SQL?”时,你需要清楚地对比这两种思维方式。想象这样的场景:你问传统数据库“张三认识的人中谁给李四转过账”——SQL 需要你编写多表 JOIN 连接,而 Cypher 只需画一个模式。
SQL 的思维模型是 把关系拆分成表。任何一张表都是“行 × 列”的集合,关系需要通过外键在查询时动态连接。查询越深,JOIN 就越多,性能也可能指数级下降。Cypher 的思维模型是 把关系作为一等公民——关系本身被存储,不需要查询时临时拼接。查询“认识的人给谁转账”这样多跳(multi-hop)的问题,SQL 可能需要三层嵌套 JOIN,而 Cypher 只需要三个箭头。
以下是对比示例(同样的查询,两种写法):
对比非常直观:SQL 需要明确连接顺序,Cypher 直接声明模式。模式匹配 vs 表连接,这是两种范式的根本差异。
回到侦探的比喻:SQL 是你要求助手“按步骤打开三个文件柜,先找人事档案,再找通话记录,再找银行流水……”;而 Cypher 是你直接把三张照片并排放在桌上说:“这三个人是一条线。”两种方式的差别,在办公室是习惯,在数据规模变大后就是性能与生产力的差异。
- SQL多表连接
σ(...(Tab1 ⋈ Tab2) ⋈ Tab3...)——每次 JOIN 都是一次笛卡尔积加过滤,层级越深计算量越大 - Cypher模式匹配
(n1)-[r]->(n2)-[r2]->(n3)——一条语句同时表达三段关系,无需拆解
-- SQL写法(两层JOIN)SELECT DISTINCT t.nameFROM Persons pJOIN Knows k ON p.id = k.person1_idJOIN Persons t ON t.id = k.person2_idJOIN Transfers tr ON tr.from_id = t.idJOIN Persons l ON l.id = tr.to_idWHERE p.name = '张三' AND l.name = '李四'
-- Cypher写法(一条模式)MATCH (p:Person {name:'张三'}) -[:KNOWS]-> (t:Person) -[:TRANSFERS]-> (l:Person {name:'李四'})RETURN t.name
执行优化
探员的幕后工作:你在线索板上轻松地画出各种模式,但你是否想过——是谁在幕后快速检索这些线索?每个查询背后,引擎都在默默地进行路线规划。就像一位资深探员接到任务后,会快速判断:先从哪个人入手?先翻哪份档案?用哪个线人?这些“幕后工作”就是查询执行优化。
Cypher 的执行流程分三个关键环节:查询计划生成、索引加速、结果缓存。当你提交一条 MATCH 语句时,Neo4j 会先进行解析(Parsing),把 Cypher 语法翻译成内部逻辑查询计划;然后通过优化器(Optimizer)生成多个候选的物理执行计划,并选择代价最小的一个——这个过程类似探员决定“从哪个证人先问起能最快破案”。
第二个关键加速机制是索引。为节点的某个属性创建索引(如 CREATE INDEX FOR (p:Person) ON (p.name)),查询时引擎会通过索引直接定位,而不是整张表扫描。这就像线索板上除了人名的照片卡之外,还有一本按照拼音排序的“姓名索引册”——告诉你“张三”的卡片在第三排左起第四张。对于图数据库,索引同样可以显著加速节点查找,而一旦找到起始节点,遍历相邻关系往往是常数级的开销。
第三个机制是内存缓存。Neo4j 通过页缓存(Page Cache)把磁盘上的图数据加载到内存中,热路径查询直接命中内存,避免磁盘 I/O。
回到侦探比喻——你写下的每条 Cypher 查询,背后都有一个聪明的“老探员”在为你规划最佳路线。理解执行优化的基本机制,能帮助你写出与引擎思路一致的查询模式,让“线索板”上的每一次追踪都又快又准。这正是从“会写查询”进阶到“写好查询”的关键一步。
- 优化器选择
min(计划代价)— 引擎在多个执行计划中选代价最小的,如同选择最快路线 - 索引加速索引将查找从线性扫描变为对数跳跃,如同按笔画查字典而非逐页翻阅
- 缓存命中热数据在内存中直接返回,避免磁盘访问导致的数量级延迟
AI 应用场景
社交网络中的影响力分析
阶段:数据探索与特征工程
解决的问题:在社交网络中找出真正的“关键意见人物”(KOL),传统 SQL 需要十几层自连接查询,效率低且难以表达“好友的好友的好友”这类多跳关系。Cypher 通过路径查询直接计算用户的社交影响力指标。
具体案例:某社交平台内容推荐团队使用 Neo4j 存储 1 亿用户的关注关系,使用 Cypher 查询 MATCH (u:User)-[:FOLLOWS*1..3]->(target:User) 计算用户的“三度影响力”,识别出传播力最强的种子用户。相比原有 SQL 方案,查询从分钟级降至秒级。
金融风控中的异常转账检测
阶段:特征提取与模式识别的数据支撑
解决的问题:洗钱行为往往通过复杂的关系链(A转账给B,B转账给C,C最终汇款给D),传统 SQL 难以高效追踪多级资金链路。Cypher 的路径模式和可变长度关系能优雅表达并快速检测可疑转账环路。
具体案例:某银行风控系统使用 Cypher 查询 MATCH (a:Account)-[t:TRANSFER]->(b:Account)-[t2:TRANSFER]->(c:Account)-[t3:TRANSFER]->(a) 识别资金闭环(即环形转账),并结合 WHERE t.amount > 50000 过滤大额交易,每周自动发现数百条可疑洗钱路径。
知识图谱驱动的智能问答
阶段:检索增强生成(RAG)中的信息检索
解决的问题:大语言模型回答事实性问题时经常“幻觉”,知识图谱提供了可验证的事实结构。通过 Cypher 从知识图谱中检索相关实体和关系,作为问答系统的上下文证据,显著提升答案准确性。
具体案例:某医疗问答系统将医学指南构建为知识图谱,使用 Cypher 查询 MATCH (d:Drug {name:'阿司匹林'})-[r:INTERACTS_WITH]->(other:Drug) RETURN other.name, r.description 获取药物相互作用信息,使问答系统回答准确率从 72% 提升至 94%。
Python 演示
from neo4j import GraphDatabase class DetectiveHelper: def __init__(self, uri, user, password): self._driver = GraphDatabase.driver(uri, auth=(user, password)) def close(self): self._driver.close() def find_associates(self, person_name, max_hops): query = """ MATCH path = (start:Person {name: $name}) -[:KNOWS*1..%d]-> (associate:Person) RETURN associate.name AS name, length(path) AS hops ORDER BY hops """ % max_hops with self._driver.session() as session: result = session.run(query, name=person_name) return [(record["name"], record["hops"]) for record in result] def find_transfer_rings(self, min_amount): query = """ MATCH (a:Account) -[t:TRANSFER]-> (b:Account) -[t2:TRANSFER]-> (c:Account) -[t3:TRANSFER]-> (a) WHERE t.amount > $min_amount AND t2.amount > $min_amount AND t3.amount > $min_amount RETURN a.id AS from_account, b.id AS mid_account, c.id AS to_account, t.amount + t2.amount + t3.amount AS total_flow LIMIT 20 """ with self._driver.session() as session: result = session.run(query, min_amount=min_amount) return [record.data() for record in result] def count_by_city(self): query = """ MATCH (p:Person) RETURN p.city AS city, COUNT(*) AS cnt ORDER BY cnt DESC """ with self._driver.session() as session: result = session.run(query) return [(record["city"], record["cnt"]) for record in result] if __name__ == "__main__": helper = DetectiveHelper("neo4j://localhost:7687", "neo4j", "password") try: print("=== 张三的关联人 ===") for name, hops in helper.find_associates("张三", 2): print(f" {name} (相距{hops}跳)") print("=== 大额转账环形路径 ===") rings = helper.find_transfer_rings(50000) for ring in rings: print(f" {ring['from_account']} -> {ring['mid_account']} -> " f"{ring['to_account']} -> ... 总额 {ring['total_flow']}") print("=== 各地人数统计 ===") for city, cnt in helper.count_by_city(): print(f" {city}: {cnt}人") finally: helper.close()
GraphDatabase.driver(uri, auth=(user, password))建立到 Neo4j 的连接驱动,这是所有查询的入口session.run(query, name=person_name)执行 Cypher 查询,参数用$name占位符避免注入"MATCH path = (start:Person {name: $name}) -[:KNOWS*1..%d]->"可变长度关系模式,查找多跳关联人length(path) AS hops计算路径长度(跳数),用于衡量关联紧密程度t.amount + t2.amount + t3.amount AS total_flow汇总环形路径上的总转账金额LIMIT 20限制返回行数,避免结果集过大导致内存溢出record.data()将 Neo4j 记录转为 Python 字典,便于结构化解构
常见误区
误区“我懂 SQL,Cypher 看起来也差不多,SELECT 大概对应 MATCH,WHERE 一样用,学起来应该很快。反正都是查询语言,就把它当 SQL 的图数据库变体就行了。”
正解Cypher 和 SQL 的根本差异在思维模型。SQL 面向“表”操作,关系需通过 JOIN 二次联结;Cypher 面向“图”操作,关系是一等公民直接存储。"MATCH (a)-[]->(b)" 不是一个 JOIN,而是描述一个存在于图中的模式。试图用 SQL 思维写 Cypher,往往会把本来优雅的图查询写成一堆不必要的 WHERE 条件,甚至刻意避开关系模式。
为何常见:SQL 是绝大多数开发者最熟悉的查询语言,新语言的语法看着有几分相似,很容易先入为主地套用 SQL 思维。
误区“图数据库里的关系就是有箭头的,从 A 指向 B。如果我想查双向关系,必须写两条语句或者创建两条关系,不然数据就丢了。”
正解Cypher 中的方向是“匹配语义”而不仅是“存储语义”。一条 (a)-[r]-(b) 不带箭头的模式可以匹配任意方向的关系;而存储时虽然关系有方向,查询时可以灵活地忽略方向。创建一条关系后,你可以用无箭头模式同时匹配两个方向,无需冗余存储。
为何常见:看到 --> 的箭头视觉冲击力强,容易让人误以为方向是数据的固有属性而非查询的匹配条件。
误区“`*1..5` 这种看起来很美好,但数据一多肯定很慢,我从来不敢用。还是要自己写多个查询分别查一跳、两跳、三跳……”
正解可变长度路径会随着步数指数增长,但这并不意味着它优于多个查询。相反,Neo4j 对可变长度遍历做了大量的优化(如双向 BFS),一次 *1..5 查询通常远快于五次独立查询。当然,合理增加 WHERE 过滤和索引,以及在确实需要时可以限定最大跳数,才是性能的关键。
为何常见:直觉上觉得“循环展开”比“一条大查询”更快,忽略了数据库引擎的批量遍历和剪枝优化能力。
误区“Cypher 只是简单的匹配工具,图数据库只能做关系查询。遇到统计分析、需要聚合运算的场景,还是得把数据导出来用 pandas 或 Spark 处理。”
正解Cypher 内置了完整的聚合函数(COUNT、SUM、AVG、PERCENTILE)、列表推导、WITH 管道、CASE 表达式,足以完成相当复杂的分析任务。MATCH ... WITH ... ORDER BY ... LIMIT ... 的组合允许你在数据库内部完成分页、Top-N、去重等操作。对于超大图上的复杂图算法(如社区发现),可以结合 GDS(图数据科学)库。
为何常见:初学者只接触了 MATCH 和 RETURN,没见过 WITH、UNWIND、CASE 等高级语法,误以为 Cypher 只能进行简单的匹配。
面试题
Q1. 在 Cypher 中,MATCH 子句的核心作用是什么?
- A.创建新的节点和关系
- B.在图中匹配一个模式← 正确答案
- C.删除不符合条件的数据
- D.对查询结果进行排序
答案:B。MATCH 是 Cypher 的模式匹配子句,用于在图中查找与给定模式匹配的子图。创建节点用 CREATE,排序用 ORDER BY,删除用 DELETE/DETACH DELETE。MATCH 就像在线索板中寻找符合“画出的模式”的片段。
Q2. 如何表示一条不带方向的关系?
- A.
(a) -[r]-> (b) - B.
(a) -[r]- (b)← 正确答案 - C.
(a) <-[r]- (b) - D.
(a) --[r]-- (b)
答案:B。不带方向的关系用 -[r]- 表示,它可以匹配任意方向的关系。--> 表示从左到右,<-- 表示从右到左,[r] 是关系变量。不带方向的关系就像一条没有箭头的线——两边都能连。
Q3. Cypher 中 WHERE 子句的作用是什么?
- A.定义节点标签
- B.过滤匹配的结果← 正确答案
- C.创建新的属性
- D.指定返回字段
答案:B。WHERE 子句用于在 MATCH 的结果上添加过滤条件,类似 SQL 中的 WHERE。它不负责定义标签(那是在节点语法中的冒号),也不负责返回字段(RETURN 负责)。WHERE 就是侦探的“线索筛选器”——筛掉不满足条件的卡片。
Q4. 以下哪个函数可以统计去重后的数量?
- A.
COUNT(*) - B.
COUNT(DISTINCT n.name)← 正确答案 - C.
SUM(n.age) - D.
AVG(n.age)
答案:B。COUNT(DISTINCT n.name) 会先对 name 属性去重,再计数。COUNT(*) 只统计行数不去重;SUM 和 AVG 是数值聚合函数,与去重无关。就像统计嫌疑人名单——你不想把同名的人重复计算进去。
Q5. 在 Cypher 中,可变长度路径 -[r:KNOWS*1..3]-> 表示什么?
- A.恰好匹配 1 个 KNOWS 关系
- B.匹配 1 到 3 个连续的 KNOWS 关系← 正确答案
- C.匹配至少 3 个 KNOWS 关系
- D.匹配恰好 3 个 KNOWS 关系
答案:B。*1..3 表示长度范围 1 到 3,即经过 1 到 3 个连续的 KNOWS 关系都能匹配。*3 恰好 3 步,*1.. 至少 1 步,*..3 最多 3 步。可变长度路径意味着——1 步也可能是 2 步、3 步,都在匹配范围内。
Q6. 以下哪些是 Cypher 相比 SQL 的优势?
- A.关系是一等公民,无需 JOIN
- B.多跳查询表达更自然
- C.所有查询都比 SQL 快
- D.模式匹配语法更直观
答案:。A、B、D 都是 Cypher 的核心优势:关系直接存储、多跳(如朋友的朋友)表达简洁、图形化语法直观。C 绝对化——Cypher 并不总比 SQL 快,对简单的单表查询 SQL 可能更高效。就像侦探找关系图上的线索比 Excel 强,但简单的数字求和还是计算器更快。
Q7. 以下哪条语句可以为 Person 节点的 name 属性创建索引?
- A.
CREATE INDEX ON :Person(name) - B.
CREATE UNIQUE INDEX ON :Person(name) - C.
CREATE INDEX FOR (p:Person) ON (p.name)← 正确答案 - D.
CREATE INDEX (p:Person) ON p.name
答案:C。Cypher 的索引创建语法是 CREATE INDEX [名称] FOR (标签:标签名) ON (变量.属性)。C 是 Neo4j 3.5+ 的标准写法。A 是过期语法,B 是唯一约束,D 语法错误。索引就像给线索卡做了一个按姓名排序的检索目录。
Q8. 在 Neo4j 中,以下哪种方式能最快找到某个节点?
- A.全图扫描并逐个比较属性
- B.通过该属性的索引查找← 正确答案
- C.先查找大标签的所有节点
- D.不做任何处理直接返回图数据
答案:B。通过索引查找将定位目标节点的时间复杂度从 O(n)(全图扫描)降到 O(log n) 或 O(1),速度提升显著。扫描某个标签的所有节点仍然是 O(n)。索引就像查字典一样——按索引直接翻到那一页,而不是从第一页开始逐页浏览。
Q9. 下列哪些是 shortestPath 函数的正确特征(以题目示例为准)?
- A.可以指定最大跳数限制
- B.返回任意一条路径
- C.返回两个节点间的最短路径
- D.只能用于无向关系
答案:。shortestPath((a)-[:KNOWS*..6]-(b)) 中 *..6 指定了最大跳数,返回的是最短路径。C 正确——它就是返回最短的那条。A 也正确——跳数限制可配置。B 错——它返回最短路径而非任意路径。D 错——有向关系同样适用。shortestPath 就是 GPS 导航中的“最短路线”,但你可以告诉它“别绕过三条街以外”。
Q10. 关于 Cypher 的 WITH 子句,以下说法正确的是?
- A.类似于 SQL 中的 HAVING
- B.可以在聚合后继续过滤
- C.可以把结果传递给后续查询
- D.与
RETURN功能完全相同
答案:。WITH 可以聚合管道(pipeline)的关键——聚合完成后用 WITH ... WHERE 做进一步过滤(类 HAVING),也可以把结果作为变量导入后续 MATCH。D 错——WITH 不同于最终 RETURN,它不终止查询而是传递中间结果。WITH 就像侦探先筛选出一批线索,再顺着这批线索继续追查——而不是直接结案。