- Published on
Neo4j 日历版本时代中期盘点 — 块格式、Cypher 25,以及 GQL 落地引擎的方式
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 引言 — 不谈 RAG,谈引擎
- 发布模型 — 每月发布,下个月支持就结束
- 存储 — 块格式成为默认值之后,record 悄然退场
- 语言 — Cypher 带上了版本号
- GQL — 从标准文档落地到更新日志的方式
- 执行引擎 — 并行运行时,以及预防死锁的调度器
- 水平扩展 — Infinigraph 属性分片,但需要单独订阅
- 该站在哪条轨道上 — 判断标准
- 结语
- 参考资料
引言 — 不谈 RAG,谈引擎
在这个博客里,图最近大多是作为 RAG 的素材出现的 — Graph RAG 是什么和运行 Graph RAG 的工具就是这条线。今天我们往下走一层。因为在真正存储图、执行查询的数据库引擎这一层,过去一年半里悄悄发生了不少大事。
舞台基本上是 Neo4j。不管喜不喜欢,它都是服务端属性图的事实默认选项(参见2026 年图数据库地形梳理),更重要的是,这个引擎目前正同时经历三场转变。发布模型变了(日历版本号),存储默认值变了(块格式),语言开始带版本号了(Cypher 5 vs Cypher 25 — 以及它背后的 ISO GQL 标准)。这三者都不是「按一下升级按钮就完事」的变化,而是都需要运维判断。
以下所有版本号、日期与政策,都是直接对照 Neo4j 官方更新日志、文档、支持政策页面以及 endoflife.date 核实的,出处都链接在正文里。
发布模型 — 每月发布,下个月支持就结束
Neo4j 在 5.26 之后放弃了语义化版本号,转向日历版本号。根据 endoflife.date 上的 Neo4j 历史,第一个 CalVer 版本 2025.01 在 2025 年 2 月初发布,此后到 2026.06(2026 年 7 月 8 日 GA)约 17 个月里,累计发布了 18 个功能版本,大致是每月一个。
重要的不是速度,而是支持政策。Neo4j 官方支持版本文档明确写道,每个版本的热修复提供期限「通常持续到下一个次版本发布为止」。实际的表格也印证了这一点 — 2026.05 的热修复在 2026.06 发布的那一刻就结束。也就是说,一个 CalVer 版本的实际寿命只有 4 到 6 周。
| 轨道 | 版本 | 状态(截至 2026-07-17) |
|---|---|---|
| LTS | 4.4 | 2025-11-30 EOL |
| LTS | 5.26(2024-12-06) | 热修复维护到 2028-06-06,最新补丁 5.26.28(2026-06-30) |
| CalVer 列车 | 2025.01 ~ 2026.06 | 只支持最新版本,旧版本立即失去支持 |
而截至本文撰写时,CalVer 系列里完全没有 LTS。支持版本文档和 endoflife.date 上,2025.x 或 2026.x 都没有任何一个版本标注为 LTS。结果就是,自托管(self-managed)环境的选项恰好只有两个。
- 停留在 5.26 LTS — 一直能拿到热修复直到 2028 年 6 月。代价是,之后发布的所有东西(Cypher 25、VECTOR 类型、新的 GQL 语法、ABAC 等)都用不了。
- 上发布列车 — 每月都能拿到新功能和 bug 修复。代价是,只要有一个月没升级,你运行的就是一个不受支持的版本。
对于习惯「一年一次大版本升级」的组织来说,不存在第三个选项,这正是这套模型的核心,也是最有争议的地方。
上车的代价也写得很具体。根据5.26 → 2025.x 升级指南,从 2025.01 起 Java 21 变为强制要求(Java 17 支持终止,Java 25 从 2025.10 起获得支持),集群发现服务 v1 被移除,因此升级前必须完成向 v2 的迁移,Kafka、Spark 连接器以及 GraphQL 库也都要升级到兼容的补丁版本以上。
存储 — 块格式成为默认值之后,record 悄然退场
CalVer 转型的底层,是存储格式的代际更替。根据官方存储格式文档,目前的现状是这样。
- block — Enterprise Edition 推荐的格式,也是不特意配置时的默认值。它把属性内联存储在与节点、关系相同的块中,以减少指针追踪,设计目标是让少数几页就能服务一次查询的数据局部性。高密度节点会溢出到基于多根世代 B+ 树的 dense store 中。
- aligned — Community Edition 的默认格式。块格式在 CE 中不存在。
- standard、high_limit — 在 5.23 中被标记为弃用(deprecated)。文档明确写着不要在新数据库中使用它们。
升级指南强烈建议 5.26 LTS 用户在升级到 2025.x 之前先完成块格式迁移。迁移有一个限制:块格式的 token 名称(标签、属性键、关系类型)最多只允许到 GQL 标识符的最大长度 16,383 个字符 — 这是 ISO 标准的痕迹第一次刻进存储格式规范里。
方向在更新日志里看得更清楚。2025.10 的更新日志把 VECTOR 介绍为「Cypher、块存储格式和 v6 驱动程序共同支持的新类型」 — 新的类型系统是建立在块格式之上生长的。反过来,遗留的 record 格式进入 2026 年后,只以纠错条目的形式出现。2026 更新日志里,2026.04 修复了「当节点在 record 格式下并发转变为 dense 时,关系遍历可能返回错误结果的 bug」,2026.06 修复了「record 格式下多种关系类型的无方向扫描会漏掉兄弟关系,导致输出结果少数约 50% 的 bug」。返回错误结果这种级别的 bug 现在才被发现,说明测试与投入的重心已经转移到了别处。如果你还坐在 record 格式上,这两条足以成为迁移申请里有分量的论据段落。
语言 — Cypher 带上了版本号
2025.06(2025 年 7 月 GA)带来了这个时代里最具概念性的变化。查询语言本身有了版本号。Cypher 版本选择文档把规则写得很精确。
- Cypher 5 已被冻结。 用
CYPHER 5执行,行为等同于「2025.06 发布时存在的那个 Cypher 5」,之后的语言变化不会影响这条查询。 - Cypher 25 持续演进。 用
CYPHER 25执行,行为等同于当前运行的 Neo4j 版本所实现的 Cypher 25。也就是说,Cypher 25 是一门随每月发布同步生长的语言。
CYPHER 25
MATCH (n:Order)-[r:SHIPPED_TO]->(:Address)
SET n = properties(r)
版本号除了可以作为查询前缀,也可以设成数据库级别的默认值(db.query.default_language),存储过程和函数(包括 APOC)同样绑定语言版本 — 同一个 APOC 发行版里,某个存储过程在 Cypher 5 下可见,到 Cypher 25 下可能已被移除。而根据 2026.02 的更新日志,新的自托管安装的默认语言已经切换为 CYPHER_25。也就是说,新装环境现在默认就是 Cypher 25。
对熟悉 Rust 的 edition 或 C++ 标准切换的人来说,这幅图景并不陌生。要在不破坏旧查询的前提下把语言向标准方向推进,就需要这套机制。不过这里藏着一处不对称 — Cypher 25 只存在于 2025.06 之后的版本中,所以停留在 5.26 LTS 的团队既用不了 Cypher 25,也用不了架在它之上的 GQL 语法。 在语言的未来和支持的稳定之间必须二选一,这就是目前的真实处境。
GQL — 从标准文档落地到更新日志的方式
ISO/IEC 39075:2024,也就是 GQL,是一份 2024 年 4 月出版的 610 页国际标准(目前处于 ISO 90.92 阶段,正在修订审查中)。它是 SQL 之后 ISO 制定的第一个数据库语言标准,这层象征意义已经被充分消费过了,这里我们只看实际的落地过程 — 标准是怎样进入一个正在运行的引擎里的。
Neo4j 的方式不是「大爆炸式切换」,而是每个月一点一点把 GQL 语法种进 Cypher 25。把更新日志按时间顺序排开,就能看到轨迹。
- 2025.06 — FILTER 子句(中间过滤)、LET 子句(中间变量投影)、用于查询线性组合的 NEXT 关键字、用花括号包裹的查询块。全部明确标注为「GQL conformant」。Cypher Shell 的默认错误格式也改成了基于 GQLSTATUS 的 gql 格式。
- 2026.02 — 批量新增了一批 GQL 兼容的函数别名,如
ceiling、local_time、zoned_datetime、collect_list、percentile_disc、stdev_pop(重定向到既有实现,行为无变化)。 - 2026.04 — UNWIND 的 GQL 替代方案 FOR .. IN 子句,以及标签检查谓词 IS LABELED。
- 2026.05 — 为 GPM 最短路径(ANY SHORTEST、SHORTEST k 等)增加了 ACYCLIC 这类显式路径模式的支持。
- 2026.07(撰稿时尚未发布,已登记在更新日志中) — WITH、RETURN 的 GROUP BY 子句(注明「为使 Cypher 更贴近 GQL 标准而引入」),以及对应 GQL 特性 GF12 的 cardinality() 函数。
把这一切概括成「Neo4j 支持 GQL」会是一种夸大。准确的状态 Neo4j 自己已经文档化了。GQL 合规性附录是依据标准 24.2 节做出的最低合规(minimum conformance)声明,支持项旁边都带着脚注 — 比如 GQL 的 FLOAT、INTEGER 有精度选项,但 Cypher 的 FLOAT 始终是 64 位 double,INTEGER 始终是 64 位。同一附录里,一份尚未支持的必备(mandatory)功能清单原样留着:GQL 的会话管理命令(SESSION SET 等)、事务命令(START TRANSACTION、COMMIT、ROLLBACK — 在 Neo4j 里这个角色由驱动 API 承担)、CURRENT_GRAPH 这类图表达式、模式选择的 AT 子句,甚至连保留字清单都存在不一致。
把视野拉到整个引擎生态,结论也差不多。Google Spanner Graph 在自己的文档里表述为提供「ISO GQL 兼容(compatible)的图查询接口」,而 Memgraph 和 FalkorDB 的文档依然把 Cypher 放在最前面。概括起来 — GQL 作为一个标准是真实存在的,但截至 2026 年年中,「用 GQL 写就能到处跑」这种可移植性并不存在。 就连标准的必备功能,也没有全部进入代表性的实现,而各家厂商的措辞(「conformant」「compatible」)彼此指向的也不是同一件事。因为 GQL 而选择引擎目前还为时过早,现阶段 GQL 带来的实际好处,诚实地说大概就是「新学的语法方向与标准一致」这个程度。
执行引擎 — 并行运行时,以及预防死锁的调度器
查询执行这一侧,在同一段时间里也一直在动。先补充一点背景:Neo4j 的并行运行时只在 Enterprise 中提供,且只支持读查询。它把流水线切分成 morsel 粒度的任务,由多个工作线程分摊处理,特点在于调度不是中央队列,而是按工作线程分布的调度器。2026.05 中,当输入基数为 1 时用 Repeat 算子来规划可变长度模式的启发式规则,默认改为关闭 — 如果你在用并行运行时,这是一个执行计划可能悄悄发生变化的地方(可以通过查询选项恢复)。
写入这一侧,2026.05 到 2026.06 之间引入的事务批调度格外显眼。当用 IN CONCURRENT TRANSACTIONS 并行执行 CALL 子查询时(大批量导入的常见模式),此前的做法是死锁发生后再检测重试,而 2026.06 引入的新 Cypher 25 语法 DISJOINT BY 则转向预防死锁的思路。它根据一个能识别将被锁定资源的表达式把行划分成批,共享资源的批依次执行,不共享资源的批则并发执行。
DISJOINT BY (expr, ...) -- 直接声明用来识别锁定资源的表达式
DISJOINT BY AUTO -- 通过对子查询的静态分析来推断锁定表达式
DISJOINT BY NONE -- 显式关闭批调度
更新日志里对局限性的描述,也原样搬过来 — AUTO 的静态分析只覆盖由唯一性约束和索引支撑的 MERGE 这类常见模式,一旦推断失败,就会在没有任何约束的情况下执行,而且它只能防止同一条外层查询产生的批之间的死锁,无法防止不同并发查询之间的死锁。 如果你曾经在大批量创建关系时被死锁重试循环折腾过,这个功能值得一试;如果没有,默认值(关闭)仍然是正确答案。
同一份更新日志里,也能看到坐在这趟列车上是什么感觉。2026.02.1 修复了「当 ON MATCH 表达式依赖于正在合并的变量时,MERGE 可能造成的数据丢失」,2026.02.3 修复了 pipelined 运行时中的 EXISTS 子查询 bug,并注明「最坏情况下存在写入错误数据的理论风险,但尚未确认有实际发生的案例」。每月发布,一方面意味着这类修复能更快送达,另一方面也意味着需要修复的回归问题同样频繁发生。如果你上了这趟列车,阅读补丁说明就必须成为每月运维工作的一部分。
水平扩展 — Infinigraph 属性分片,但需要单独订阅
更新日志里反复出现的「sharded property database」,是一种名为 Infinigraph 的分布式架构。它的结构很有意思,不是把整张图整体分区,而是把结构和属性分离开。节点、关系的结构原封不动地留在单一的「图分片」里,只有属性通过哈希函数均匀分散到多个「属性分片」上。文档的说法是查询语义和 ACID 保证都得以保留,而且因为图遍历在结构分片内部就能完成,这个设计避开了分布式连接的地狱。
反过来说,局限也很明确 — 结构本身仍然必须容纳在一个分片里,所以这是为「属性很重的图」设计的扩展方案,而不是为「结构本身超出单机容量的图」设计的。而且关键的一点是,正如文档明确写的那样,这是一个不包含在标准 Enterprise Edition 里的独立 Infinigraph 订阅产品(需要联系销售)。引擎层面的开发依然能在公开的更新日志里持续看到 — 2026.07 的更新日志(尚未发布)里,已经列出了面向分片部署的批量索引查找算子(RemoteNodeIndexSeek)。功能的存在与能否访问该功能是两回事,这就是这一节的事实全貌。
该站在哪条轨道上 — 判断标准
归纳起来,分野大致是这样。
停留在 5.26 LTS 时
- 升级窗口按季度或半年绑定,支持合同对运维环境很重要。热修复维护到 2028 年 6 月(5.26.28 在 2026 年 6 月 30 日仍在发布)。
- 不过,块格式迁移最好现在就做 — 反正它本来就是 5.26 的默认值,而且被作为日后转向 CalVer 的前置条件推荐。
- 接受没有 Cypher 25、VECTOR 类型、新 GQL 语法、ABAC 的日子。
上 CalVer 发布列车时
- 有能自动化每月(至少每两月)升级的流水线,以及阅读补丁说明的运维习惯。
- Cypher 25 的新语法或向量功能是真实的需求。
- 组织理解「受支持的版本永远只有最新那一个」这个事实。
如果是 Community Edition — 更准确的想法是,你在使用一个既没有块格式也没有并行运行时(aligned 格式、单线程运行时)的另一个产品。从引擎角度看,这一代改进的大部分都落在了 EE 那边。
如果瞄准的是 GQL 可移植性 — 这目前还只是一个方向,不是一份契约。只要标准必备功能的未支持清单还原样留在代表性实现的文档里,GQL 能保证的就不会超过「提前学会一套方向对的语法,方便日后有需要时切换」。
如果原本在找嵌入式图引擎 — 这个地形去年秋天经历了一次大震动。曾是嵌入式代表的 Kùzu,其代码仓库已于 2025 年 10 月 10 日被归档(最后一个版本 v0.11.3,仓库地址),目前正在延续到社区分叉版本中。选项梳理已经在工具篇里做过,请参考那篇文章。
结语
把 CalVer 转型后一年半的 Neo4j 压缩成一句话,就是这样 — 引擎在块格式之上每月生长,语言正以版本为单位向 GQL 靠拢,而这个速度的代价,由「受支持的版本永远只有最新那一个」这套运维模型来承担。 标准(GQL)已经出版,但可移植性还没有真正到来,想要 LTS 的团队和想要新功能的团队,目前的距离几乎相当于在使用两个不同的大版本。
如果你只把图当作 RAG 的素材来用,这篇文章的大部分内容眼下都与你无关 — 那是隐藏在托管服务或嵌入式存储背后的一层。但如果你直接运维图数据库,或者正在挑选引擎,又或者需要评估「支持 GQL 标准」这句营销话术,判断所需的材料不在厂商的宣传幻灯片里,而在上面链接的更新日志和合规性文档里。标准落地到引擎的过程并不华丽。一个月一个月地来,一个子句一个子句地加,一批函数别名一批函数别名地补 — 这就是它实际的样子。
参考资料
- Neo4j 2026 更新日志(GitHub Wiki)
- Neo4j 2025 更新日志(GitHub Wiki)
- Neo4j 支持版本政策(官方 KB)
- Neo4j 版本历史 — endoflife.date
- 从 5.26 LTS 到 2025.01 之后的变更 — 升级指南
- 存储格式 — 运维手册
- Cypher 版本选择 — Cypher 手册
- GQL 合规性附录 — Cypher 手册 以及未支持的必备功能清单
- Cypher 运行时概念(并行运行时) — Cypher 手册
- Infinigraph 属性分片概览 — 运维手册
- ISO/IEC 39075:2024 — GQL 标准
- Spanner Graph 概览 — Google Cloud 文档
- Memgraph 查询文档、FalkorDB Cypher 文档
- Kùzu 仓库(2025-10 归档)