From 76fa08eaa50ac1ce442941973a11367337ce6dda Mon Sep 17 00:00:00 2001 From: contrueCT Date: Mon, 19 Oct 2026 18:12:53 +0800 Subject: [PATCH 1/4] docs: add 1.8 Gremlin and TinkerPop 3.8 migration guide (#541) - Add comprehensive bilingual migration guides for TinkerPop 3.8.1 upgrade - Highlight top 6 high-frequency syntax changes with code examples - Categorize edge cases and protocol references into quick-access tables - Update Gremlin language reference step and feature tables - Align Server quickstart and introduction with 1.8.0 release scopes - Draft 1.8.0 release notes with Gremlin breaking changes summary --- .../hugegraph-1.8.0-release-notes.md | 42 ++++ .../cn/docs/guides/gremlin-migration-3.8.md | 192 ++++++++++++++++++ content/cn/docs/introduction/_index.md | 2 +- content/cn/docs/language/hugegraph-gremlin.md | 11 +- .../quickstart/hugegraph/hugegraph-server.md | 4 +- .../hugegraph-1.8.0-release-notes.md | 42 ++++ .../en/docs/guides/gremlin-migration-3.8.md | 189 +++++++++++++++++ content/en/docs/introduction/_index.md | 2 +- content/en/docs/language/hugegraph-gremlin.md | 11 +- .../quickstart/hugegraph/hugegraph-server.md | 5 +- 10 files changed, 490 insertions(+), 10 deletions(-) create mode 100644 content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md create mode 100644 content/cn/docs/guides/gremlin-migration-3.8.md create mode 100644 content/en/docs/changelog/hugegraph-1.8.0-release-notes.md create mode 100644 content/en/docs/guides/gremlin-migration-3.8.md diff --git a/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md b/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md new file mode 100644 index 0000000000..66031305a7 --- /dev/null +++ b/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md @@ -0,0 +1,42 @@ +--- +title: "HugeGraph 1.8.0 Release Notes" +linkTitle: "Release-1.8.0" +weight: 1 +--- + +> WIP: This doc is under construction, please wait for the final version (BETA) + +### 运行环境/版本说明 + +- **Java 运行环境**:**1.8.0** 版 HugeGraph 组件(Server、PD、Store)统一要求 **Java 17** 运行与源码构建环境(1.7.0 是最后一个支持 Java 11 的版本)。 +- **查询与脚本引擎**:图遍历与查询框架升级至 **Apache TinkerPop 3.8.1**,脚本引擎统一升级至 **Groovy 4.0.25**。 + +### 升级与兼容性重点(Breaking Changes) + +#### 1. Gremlin 查询语法重要破坏性变更 +- **移除 `has(key, traversal)` 重载**:Groovy 下旧写法不再报错,而是静默命中 Object 比较导致**空结果/0 条数据**。简单条件直写谓词 `has('age', gt(30))`,复杂过滤改用 `filter(__.values('age').is(gt(30)))`。 +- **移除 `store()` 与带 Scope 的 `aggregate()`**:全局贪心收集统一改用 `aggregate('x')`,局部/逐对象收集改用 `local(__.aggregate('x'))`。 +- **无参 `none()` 更名为 `discard()`**:丢弃输入遍历必须使用 `discard()`(避免与新集合过滤 `none(P)` 冲突)。 +- **`by()` 缺失属性严检**:缺失属性在 `order().by()` 下直接过滤顶点,在 `project().by()` 下不再返回该 key,在 `path().by()` 下直接过滤路径;需保留缺失字段请在 `by()` 中显式使用 `coalesce()` 补默认值。 +- **`choose()` 分支语义收敛**:多条件重叠仅执行首个匹配分支;无匹配或属性缺失默认原样放行穿透(需过滤请显式加 `Pick.none` / `Pick.unproductive` 分支配合 `discard()`)。 +- **日期类型与单位变更**:日期操作产出由 `java.util.Date` 转向 `OffsetDateTime`;`dateDiff()` 差值单位从**秒变为毫秒**。 + +> 完整改写代码对照与全量细则速查表请参阅:[HugeGraph 1.8.0 Gremlin 迁移与兼容性指南](../guides/gremlin-migration-3.8)。 + +#### 2. 服务端配置与客户端兼容 +- **Serializer 类名迁移**:`conf/gremlin-server.yaml` 中序列化器包路径由 `org.apache.tinkerpop.gremlin.driver.ser.*` 迁移至 `org.apache.tinkerpop.gremlin.util.ser.*`。 +- **HugeGraph Client 1.5.0**:服务端提供向后兼容适配,1.5.0 客户端无需换包可正常连通 1.8.0 服务端;但客户端拼接的 Gremlin 脚本需按 3.8 语法规范调整。 +- **移除内置 GPL word 分词器**:统一使用 IK、SmartCN 等合规分词器。 + +--- + +### hugegraph + +#### API Changes +- **BREAKING CHANGE**: Upgrade TinkerPop to 3.8.1 and require Java 17 runtime +- **BREAKING CHANGE**: Shared foundation module migration (`hugegraph-struct`) + +#### Feature Changes +- Support TinkerPop 3.8 steps including `discard()`, `mergeV()`, `mergeE()`, and `datetime()` +- Adapt HugeSecurityManager and Groovy 4.0.25 on Java 17 +- Improve count query visibility inside uncommitted transactions diff --git a/content/cn/docs/guides/gremlin-migration-3.8.md b/content/cn/docs/guides/gremlin-migration-3.8.md new file mode 100644 index 0000000000..2dac113614 --- /dev/null +++ b/content/cn/docs/guides/gremlin-migration-3.8.md @@ -0,0 +1,192 @@ +--- +title: "HugeGraph 1.8.0 Gremlin 迁移与兼容性指南" +linkTitle: "1.8 Gremlin 与 TinkerPop 迁移" +description: "详细说明 HugeGraph 1.8.0 从 TinkerPop 3.5 升级到 3.8 带来的核心语法兼容性变化、常用改写方案、配置调整及全量细则速查表。" +weight: 9 +--- + +HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升级至 **TinkerPop 3.8.1**,运行环境统一要求 **Java 17**(服务端与构建),并将脚本引擎升级至 **Groovy 4.0.25**。 + +本次升级在大幅提升性能与规范性的同时,引入了部分语言层面的破坏性变更(Breaking Changes)。本文重点列出**最常用且行为发生变化的核心语法与改写方案**,帮助已有应用和脚本顺利平滑迁移;次常用及底层协议等边缘细节已归拢至文末的[全量细则速查表](#全量细则速查表)。 + +> [!NOTE] +> - 本指南适用于从 1.7.0(或更早版本)升级至 1.8.0 的用户。 +> - 1.8.0 依然保留了 **Groovy 脚本引擎**支持,既有的多行脚本、变量定义及 Java 闭包等大多数逻辑仍可正常运行。 + +--- + +## 核心重点:最常用的 6 大语法与行为变化 + +在已有的业务查询中,以下 6 项改动最为高频,**若不改写可能直接导致查询报错或静默返回空结果(查询不到数据)**,请优先重点排查。 + +### 1. `has(key, traversal)` 重载删除(高危:静默返回空结果) + +* **影响说明**: + 在 3.8.0 中,`has(String, Traversal)` 和 `has(T, Traversal)` 重载被彻底移除。 + 在 Groovy 脚本引擎下,旧写法不会抛出编译错误,而是会**静默命中 `has(String, Object)` 重载**——即把子遍历对象本身作为属性值去图里比对,实测**直接返回 0 条结果/空结果**! +* **典型旧写法**: + ```groovy + // 错误!3.8 下不会报错,但会静默返回空结果 + g.V().has('age', __.is(gt(30))) + g.V().has(T.label, __.is('person')) + ``` +* **推荐改写方案**: + ```groovy + // 简单标量/谓词判断,直接传值或 P 谓词 + g.V().has('age', gt(30)) + g.V().hasLabel('person') + g.V().hasId('v-1') + + // 若需要把属性值传给复杂子遍历计算后再过滤,改用 filter() + g.V().filter(__.values('age').is(gt(30))) + ``` + +--- + +### 2. `store()` 彻底删除 & `aggregate()` Scope 重载移除 + +* **影响说明**: + - 旧版中用于惰性边走边收集副作用的 `store('x')` 步骤已被完全删除,直接报错 `No signature of method: store()`。 + - `aggregate(Scope, 'x')` 的带 Scope 重载也被删除(包括 `aggregate(local, 'x')` 和 `aggregate(global, 'x')`)。 +* **典型旧写法**: + ```groovy + // 错误!store 步骤已被移除 + g.V().store('x').by('age').cap('x') + + // 错误!aggregate 的 scope 重载已被移除 + g.V().aggregate(local, 'x') + g.V().aggregate(global, 'x') + ``` +* **推荐改写方案**: + ```groovy + // 1. 全局贪心收集(原 global 聚合):直接使用 aggregate('x') + g.V().aggregate('x').by('age').cap('x') + + // 2. 局部/惰性逐个对象收集(原 store 或 local 聚合):使用 local(__.aggregate('x')) + g.V().local(__.aggregate('x').by('age')).cap('x') + ``` + +--- + +### 3. 丢弃输入步骤 `none()` 更名为 `discard()` + +* **影响说明**: + 无参的 `none()` 原本用于丢弃流中的所有输入(如在 `choose()` 或 `coalesce()` 结尾丢弃未匹配元素)。3.8.0 中该操作更名为 **`discard()`**。 + 3.8 同时引入了新的集合谓词步骤 `none(P)`(用于检查集合是否没有元素满足条件)。若在旧代码中写无参的 `none()`,极易误命中或抛出参数异常。 +* **推荐改写方案**: + ```groovy + // 旧写法:丢弃未匹配元素 + g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.none()) // 错误 + + // 新写法:统一使用 discard() + g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) + ``` + +--- + +### 4. `by()` 属性缺失行为变严(可能导致排序丢点、投影丢字段、路径丢失) + +* **影响说明**: + TinkerPop 3.6+ 统一了 `by()` 调制器的缺失值处理(去除了原先部分默认补 null 的策略)。在 3.8.1 中,当 `by()` 依赖的属性不存在时: + 1. **排序 `order().by('age')`**:缺少 `age` 属性的顶点**直接被过滤掉**(旧版可能保留在开头或末尾)。 + 2. **投影 `project('name', 'age').by('name').by('age')`**:若某个顶点缺少 `age`,返回的 Map 中**将直接不包含 `age` 键**(旧版会返回 `age: null`)。 + 3. **路径 `path().by('age')`**:路径上若有任一节点缺少该属性,**整条路径将被直接丢弃**。 +* **推荐改写方案**: + 如果业务要求在属性缺失时仍保留元素并填入默认值(如 `null` 或默认占位值),需在 `by()` 中使用 `coalesce()` 显式保底: + ```groovy + // 保证缺 age 时依然保留该字段,且值为 null + g.V().project('name', 'age') + .by('name') + .by(__.coalesce(__.values('age'), __.constant(null))) + + // 排序时为缺失属性指定统一后置的默认值(需保持数据类型一致) + g.V().order().by(__.coalesce(__.values('age'), __.constant(-1)), desc) + ``` + +--- + +### 5. 分支条件 `choose()` 语义收敛 + +* **影响说明**: + - **单分支执行**:当多个 `option()` 条件同时命中时,旧版可能会把多个匹配分支全部执行;新版**只执行第一个命中的分支**。 + - **默认放行机制**:如果选择子遍历不产值(例如没有对应的属性),或没有任何一个 `option()` 匹配,新版**默认将输入元素原样向下游放行**(旧版通常会过滤掉)。 +* **推荐改写方案**: + - 如需在多个条件同时命中时全部执行,请使用 `union()` 配合 `filter()`。 + - 如需在无匹配或属性缺失时将元素过滤抛弃,需显式声明 `Pick.none` 与 `Pick.unproductive` 分支: + ```groovy + // 显式丢弃无匹配与属性缺失项 + g.V().choose(__.values('age')) + .option(gt(30), __.values('name')) + .option(Pick.none, __.discard()) + .option(Pick.unproductive, __.discard()) + ``` + +--- + +### 6. 日期类型与时间差单位变化 + +* **影响说明**: + - **类型转向**:`datetime()`、`dateAdd()` 等日期操作的默认返回类型从 `java.util.Date` 转向 **`java.time.OffsetDateTime`**。 + - **单位由秒变毫秒**:`dateDiff()` 计算两个日期的差值,结果单位**从秒(s)改为毫秒(ms)**(例如相隔 1 天的结果由 `86400` 变为 `86400000`)。 +* **推荐改写方案**: + - Java 客户端与 SDK 应使用 `OffsetDateTime` 接收时间对象;若确需原生 `java.util.Date`,可通过 `Date.from(offsetDateTime.toInstant())` 进行转换。 + - 检查业务代码中所有涉及 `dateDiff()` 的比较阈值、TTL 策略及时间报表,将原先基于秒的计算乘以 1000 或显式除以 1000: + ```groovy + // 将 dateDiff 毫秒转换为秒 + g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z')) + .math('_ / 1000').asNumber(GType.LONG) + ``` + +--- + +## 服务端配置与客户端连接兼容 + +### 1. 服务端 Serializer 类名与包名迁移 +在 `conf/gremlin-server.yaml` 中,TinkerPop 3.8 将序列化器从 `gremlin-driver` 包分离到了 `gremlin-util` 包中。**必须更新 YAML 中的全限定类名,旧类名不是兼容别名,否则启动时将报 ClassNotFoundException**: + +| 旧配置类名 (`driver.ser.*`) | 1.8.0 对应类名 (`util.ser.*`) | 说明 | +|---|---|---| +| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | 推荐,默认高效二进制协议 | +| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | 保持无类型 JSON(不可只去掉 d0,否则会变成 typed) | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | 标准 Typed GraphSON V3 | +{.td-table--wide} + +### 2. HugeGraph Client 1.5.0 能否平滑使用? +* **结论**:**可以继续使用**。 +* 服务端在 1.8.0 中增加了向前兼容层(图别名自动映射与旧认证路径重定向),使用 `hugegraph-client:1.5.0` 进行常规 CRUD、Schema 操作及 REST 请求均可正常连通。 +* **特别注意**:虽然 Client 1.5.0 能建立连接,但客户端所发送的 **Gremlin 脚本内容依然在服务端的 3.8.1 引擎中执行**。因此,客户端代码中拼接的 Gremlin 脚本必须按照上述规则适配。 + +--- + +## 全量细则速查表 + +除上述高频变化外,TinkerPop 3.5.1 → 3.8.1 还包含若干深层优化与边缘语义调整。如遇特定场景异常,请查阅下表对应项: + +### 附录 1:写入与 Upsert(`mergeV` / `mergeE`) +从 3.6.0 开始推荐使用标准的 `mergeV()` 与 `mergeE()` 执行图数据 Upsert 操作: +- **M01**: `onCreate` 的属性 Map 严格继承主匹配 Map,不允许用冲突值覆盖主匹配条件(如匹配条件是 `name: 'A'`,`onCreate` 不能设 `name: 'B'`)。 +- **M02**: `mergeE` 不再隐式拿上游顶点填补端点,必须在 Map 中指明 `(Direction.OUT)` 与 `(Direction.IN)`,或使用 `option(Merge.outV, ...)` 显式绑定。 +- **M03**: `onMatch` 与 `onCreate` 的属性冲突在构造期就会被严格校验,而非等到运行时才报错。 +- **M04**: `onMatch` 子遍历在 3.8 中接收的是当前已匹配到的 Element 对象,而非最开始输入的 Map。若需引用外部输入参数,请在 merge 前通过 `.as('input')` 保存引用,内部通过 `select('input')` 取值。 + +### 附录 2:遍历内部高级步骤与集合行为 +- **B07 (`local()` 拆 bulk)**:带 bulk 计数的 Traverser 经过 `local()` 子遍历时会被展开为单个对象处理。若需统计频次,建议使用 `groupCount()`。 +- **B09 (`range(local)` 集合解包)**:对列表截取单元素(如 `limit(local, 1)`),新版始终返回 Collection 包装(如 `[1]`),若业务必须获取标量,请在后续追加 `.unfold()`。 +- **B11 (`sum()` 返回类型)**:整数流的 `sum()` 结果可能直接返回 Integer 而不是 Long(若无溢出),建议 Java 端统一使用 `Number` 接收。 +- **B14 (`split('')`)**:空字符串分隔符在 3.8 中将拆分为单字符列表(如 `'abc'` 拆分为 `['a','b','c']`)。 +- **B15 (`asString()` 遇 null)**:`asString()` 接收到 null 时会抛出异常,如需兼容 null 请配合 `choose()` 显式处理。 + +### 附录 3:多语言客户端差异(GLV) +- **Python**:步骤名避免与 Python 关键字冲突,全面使用下划线后缀(如 `filter_()`、`id_()`、`range_()`、`max_()` 等),推荐使用 snake_case(如 `has_label`)。 +- **JavaScript**:返回的集合从 Array 转为真正的 ECMAScript `Set`(通过 `.size`、`.has()` 操作);移除废弃的 `connectOnStartup` 选项,需使用 `await connection.open()`。 +- **.NET**:byte 类型严格按有符号整数(sbyte)序列化。 +- **Go**:BigDecimal/BigInt 解析对齐,必须始终检查 `Next()` 的 error 返回。 + +### 附录 4:底层协议与序列化边界 +- **C03 (OLTP 元素属性携带)**:远程查询返回的 Vertex/Edge 默认携带属性,不再仅是轻量引用的 id/label。若只关注特定业务字段,建议显式通过 `project()` 或 `valueMap()` 投影,避免网络负载膨胀。 +- **C06 (GraphSON 载荷安全限制)**:新增数字长度(默认 10,000)、字符串长度(默认 20,000,000)与嵌套深度(默认 1,000)反序列化上限,避免深层 JSON 导致 OOM。 + +### 附录 5:HugeGraph 适配与能力边界 +- **不支持 Meta-Properties**:HugeGraph 严格遵循自有 Schema 体系,不支持 TinkerPop 的属性元数据(属性上的属性)。在 1.8.0 中若向属性写入 metadata 将被**显式拒绝**,不再隐式退化。 +- **图计算限制**:`supportsComputer()` 仍为 `false`,依赖 `GraphComputer` 的步骤(如 `pageRank()`、`peerPressure()`)不能在 OLTP 引擎上直接执行,建议使用 HugeGraph 的专门算法 API 或 Vermeer 组件。 +- **统一列表特性**:`supportsUniformListValues()` 现返回 `false`;图中的 List 属性依然由 HugeGraph 内部 Schema (`valueList()`) 提供完整支持。 diff --git a/content/cn/docs/introduction/_index.md b/content/cn/docs/introduction/_index.md index 52ac1955d8..a7e97fd61f 100644 --- a/content/cn/docs/introduction/_index.md +++ b/content/cn/docs/introduction/_index.md @@ -43,7 +43,7 @@ HugeGraph Server 是图数据库的 OLTP 引擎和服务入口,负责属性图 - **查询语言**:支持 Gremlin(TinkerPop 3)和 Cypher(OpenCypher) - **REST API**:提供 Schema、图数据、查询、任务和运维接口 - **索引与查询**:支持精确查询、范围查询和复合条件查询 -- **存储后端**:1.7.0 至 `master` 主要支持 RocksDB(单机)、HStore(分布式)和 HBase +- **存储后端**:支持 RocksDB(单机推荐)、HStore(分布式推荐)和 HBase(自 1.7.0 起已废弃 Cassandra、MySQL、PostgreSQL 等旧后端) 主要模块包括 `hugegraph-core`、存储后端模块和 `hugegraph-api`。Core 实现图模型、事务和查询逻辑,后端模块负责连接具体存储系统,API 模块负责 HTTP 接入。当前 REST 资源路径包含图空间与图名称,例如: diff --git a/content/cn/docs/language/hugegraph-gremlin.md b/content/cn/docs/language/hugegraph-gremlin.md index 405e31fa99..4cf760a209 100644 --- a/content/cn/docs/language/hugegraph-gremlin.md +++ b/content/cn/docs/language/hugegraph-gremlin.md @@ -10,6 +10,10 @@ HugeGraph支持[Apache TinkerPop3](https://tinkerpop.apache.org)的图形遍历 Gremlin可用于创建图的实体(Vertex和Edge)、修改实体内部属性、删除实体,更主要的是可用于执行图的查询及分析操作。 +> [!NOTE] +> **版本与升级提示**:HugeGraph 1.8.0 已将底层 TinkerPop 引擎升级至 **3.8.1**(同时要求 Java 17 与 Groovy 4.0.25)。 +> 部分旧版语法(如 `store()`、`has(key, traversal)`、带 Scope 的 `aggregate()`)已被废弃或语义调整。详见 [1.8 Gremlin 与 TinkerPop 迁移指南](../guides/gremlin-migration-3.8)。 + ### TinkerPop Features HugeGraph实现了TinkerPop框架,但是并没有实现TinkerPop所有的特性。 @@ -80,7 +84,7 @@ HugeGraph实现了TinkerPop框架,但是并没有实现TinkerPop所有的特 | SerializableValues | | false | | StringArrayValues | | false | | StringValues | | true | -| UniformListValues | Supports setting of a {@code List} value. The assumption is that the {@code List} can contain arbitrary serializable values that may or may not be defined as a feature itself. As this{@code List} is "uniform" it must contain objects of the same type. | true | +| UniformListValues | Supports setting of a {@code List} value. The assumption is that the {@code List} can contain arbitrary serializable values that may or may not be defined as a feature itself. As this{@code List} is "uniform" it must contain objects of the same type. | false (由 Schema 的 valueList() 机制支持) | ### Gremlin的步骤 @@ -96,7 +100,9 @@ HugeGraph支持Gremlin的所有步骤。有关Gremlin的完整参考信息,请 | coalesce | 返回第一个返回结果的遍历 | [coalesce step](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) | | constant | 返回常量值。 与`coalesce`配合使用 | [constant step](http://tinkerpop.apache.org/docs/current/reference/#constant-step) | | count | 从遍历返回计数 | [count step](http://tinkerpop.apache.org/docs/current/reference/#count-step) | +| datetime | 构造日期时间对象或取得服务器当前时间(1.8.0 默认返回 `OffsetDateTime`) | [datetime step](http://tinkerpop.apache.org/docs/current/reference/#datetime-step) | | dedup | 返回已删除重复内容的值 | [dedup step](http://tinkerpop.apache.org/docs/current/reference/#dedup-step) | +| discard | 丢弃流中当前输入(1.8.0 替代原无参 `none()`) | [discard step](http://tinkerpop.apache.org/docs/current/reference/#discard-step) | | drop | 丢弃值(顶点/边缘) | [drop step](http://tinkerpop.apache.org/docs/current/reference/#drop-step) | | fold | 充当用于计算结果聚合值的屏障 | [fold step](http://tinkerpop.apache.org/docs/current/reference/#fold-step) | | group | 根据指定的标签将值分组 | [group step](http://tinkerpop.apache.org/docs/current/reference/#group-step) | @@ -116,7 +122,8 @@ HugeGraph支持Gremlin的所有步骤。有关Gremlin的完整参考信息,请 | repeat | 将步骤重复指定的次数。 用于循环 | [repeat step](http://tinkerpop.apache.org/docs/current/reference/#repeat-step) | | sample | 用于对遍历返回的结果采样 | [sample step](http://tinkerpop.apache.org/docs/current/reference/#sample-step) | | select | 用于投影遍历返回的结果 | [select step](http://tinkerpop.apache.org/docs/current/reference/#select-step) | -| store | 用于遍历返回的非阻塞聚合 | [store step](http://tinkerpop.apache.org/docs/current/reference/#store-step) | +| mergeV | 按属性匹配顶点,存在则更新,不存在则创建(标准 Upsert 步骤) | [mergeV step](http://tinkerpop.apache.org/docs/current/reference/#mergevertex-step) | +| mergeE | 按属性与端点匹配边,存在则更新,不存在则创建(标准 Upsert 步骤) | [mergeE step](http://tinkerpop.apache.org/docs/current/reference/#mergeedge-step) | | tree | 将顶点中的路径聚合到树中 | [tree step](http://tinkerpop.apache.org/docs/current/reference/#tree-step) | | unfold | 将迭代器作为步骤展开 | [unfold step](http://tinkerpop.apache.org/docs/current/reference/#unfold-step) | | union | 合并多个遍历返回的结果 | [union step](http://tinkerpop.apache.org/docs/current/reference/#union-step) | diff --git a/content/cn/docs/quickstart/hugegraph/hugegraph-server.md b/content/cn/docs/quickstart/hugegraph/hugegraph-server.md index 9ef4904a00..e6a6a774f8 100644 --- a/content/cn/docs/quickstart/hugegraph/hugegraph-server.md +++ b/content/cn/docs/quickstart/hugegraph/hugegraph-server.md @@ -15,7 +15,7 @@ aliases: `hugegraph-server` 模块包含 `hugegraph-core`、`hugegraph-api`、`hugegraph-dist` 和存储适配等子模块。Core 实现属性图模型、事务与 TinkerPop 接口,API 提供 HTTP 服务并将客户端请求交给 Core 处理。图数据由 RocksDB(单机默认)、HStore(分布式)或 HBase 后端保存。 > [!WARNING] -> **版本说明**:本文区分已发布版本与开发主线。下载示例使用 ASF 发布的 HugeGraph 1.7.0 安装包;源码构建、配置默认值和启动行为以 `apache/hugegraph` 的 `master` 分支为准。主线源码构建出的包不是 ASF 发布包,即使包内版本号与发布版本一致也不代表属于官方发布包。本文介绍 RocksDB、HStore 和 HBase;其他旧后端请参考 [HugeGraph 1.5.x 文档](https://github.com/apache/hugegraph-doc/blob/release-1.5.0/content/cn/docs/quickstart/hugegraph/hugegraph-server.md)。 +> **版本说明**:本文区分已发布版本与开发主线。已发布的官方包请使用对应版本的正式安装包(如 1.7.0 或即将发布的 1.8.0);源码构建、配置默认值和启动行为以 `apache/hugegraph` 的 `master` 分支(当前对应 1.8.0 开发版本)为准。主线源码构建出的包不是 ASF 发布包,即使包内版本号与发布版本一致也不代表属于官方发布包。存储后端支持 RocksDB、HStore 和 HBase;已废弃的旧后端请参考 [HugeGraph 1.5.x 文档](https://github.com/apache/hugegraph-doc/blob/release-1.5.0/content/cn/docs/quickstart/hugegraph/hugegraph-server.md)。 > 名称说明:`HugeGraph` 表示整个项目或主仓库,`hugegraph-server` 表示仓库中的 Server 模块,`HugeGraphServer` 是服务进程的 Java 类名。下文的 Server 服务指运行中的图数据库服务。 @@ -90,7 +90,7 @@ serializer: ``` > [!TIP] -> 完整客户端配置与验证细节见 [Server 运行时文档](https://github.com/apache/hugegraph/blob/master/docs/server-runtime.md)。 +> 完整的 Gremlin 语法改写、兼容性要求与速查表请参阅 [1.8 Gremlin 与 TinkerPop 迁移指南](../../guides/gremlin-migration-3.8)。更多运行时细节见 [Server 运行时文档](https://github.com/apache/hugegraph/blob/master/docs/server-runtime.md)。 ## 3 部署 diff --git a/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md b/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md new file mode 100644 index 0000000000..f416915972 --- /dev/null +++ b/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md @@ -0,0 +1,42 @@ +--- +title: "HugeGraph 1.8.0 Release Notes" +linkTitle: "Release-1.8.0" +weight: 1 +--- + +> WIP: This doc is under construction, please wait for the final version (BETA) + +### Runtime & Version Requirements + +- **Java Environment**: **1.8.0** HugeGraph components (Server, PD, Store) require **Java 17** for runtime and source builds (1.7.0 is the last release supporting Java 11). +- **Query & Script Engine**: Graph traversal framework upgraded to **Apache TinkerPop 3.8.1**, script engine upgraded to **Groovy 4.0.25**. + +### Key Breaking Changes & Compatibility + +#### 1. Critical Gremlin Traversal Breaking Changes +- **Removed `has(key, traversal)` overload**: In Groovy, legacy syntax silently falls back to Object comparison, resulting in **0 results / empty sets** without throwing an error. Use `has('age', gt(30))` for simple conditions, or `filter(__.values('age').is(gt(30)))` for child traversals. +- **Removed `store()` & scoped `aggregate()`**: Use `aggregate('x')` for global eager collection; use `local(__.aggregate('x'))` for lazy or per-object collection. +- **Step `none()` renamed to `discard()`**: Discarding incoming traversers must now use `discard()` (avoids collision with new collection predicate `none(P)`). +- **Strict `by()` behavior on missing properties**: Vertices missing properties are dropped in `order().by()`; keys are omitted from maps in `project().by()`; paths are discarded in `path().by()`. Wrap with `coalesce()` to provide explicit defaults if preservation is needed. +- **`choose()` semantics alignment**: Executes only the first matching branch when conditions overlap; passes elements through unchanged by default when no branch matches or values are absent. +- **Date types & unit changes**: Date operations return `OffsetDateTime` instead of `java.util.Date`; `dateDiff()` results are in **milliseconds instead of seconds**. + +> For comprehensive query comparison examples and the full migration checklist, see the [HugeGraph 1.8.0 Gremlin Migration & Compatibility Guide](../guides/gremlin-migration-3.8). + +#### 2. Server Configuration & Client Compatibility +- **Serializer class names**: Serializer packages in `conf/gremlin-server.yaml` moved from `org.apache.tinkerpop.gremlin.driver.ser.*` to `org.apache.tinkerpop.gremlin.util.ser.*`. +- **HugeGraph Client 1.5.0**: Supported via server-side backward-compatibility adapters; however, Gremlin query strings must follow TinkerPop 3.8 syntax. +- **GPL word analyzer removed**: Use IK, SmartCN, or other compliant analyzers. + +--- + +### hugegraph + +#### API Changes +- **BREAKING CHANGE**: Upgrade TinkerPop to 3.8.1 and require Java 17 runtime +- **BREAKING CHANGE**: Shared foundation module migration (`hugegraph-struct`) + +#### Feature Changes +- Support TinkerPop 3.8 steps including `discard()`, `mergeV()`, `mergeE()`, and `datetime()` +- Adapt HugeSecurityManager and Groovy 4.0.25 on Java 17 +- Improve count query visibility inside uncommitted transactions diff --git a/content/en/docs/guides/gremlin-migration-3.8.md b/content/en/docs/guides/gremlin-migration-3.8.md new file mode 100644 index 0000000000..fdfa1145fb --- /dev/null +++ b/content/en/docs/guides/gremlin-migration-3.8.md @@ -0,0 +1,189 @@ +--- +title: "HugeGraph 1.8.0 Gremlin Migration & Compatibility Guide" +linkTitle: "1.8 Gremlin & TinkerPop Migration" +description: "Comprehensive guide to breaking changes, high-frequency syntax rewrites, configuration migrations, and complete compatibility references from TinkerPop 3.5 to 3.8 in HugeGraph 1.8.0." +weight: 9 +--- + +HugeGraph 1.8.0 upgrades its underlying graph traversal and query framework from Apache TinkerPop 3.5.1 to **TinkerPop 3.8.1**, requires **Java 17** for Server and builds, and updates the script engine to **Groovy 4.0.25**. + +While bringing substantial performance optimizations and specification alignments, this upgrade introduces several language-level breaking changes. This guide highlights the **most critical and frequently used syntax changes** with recommended rewrites to ensure seamless migration. Edge cases and lower-level protocol details are organized in the [Full Compatibility Reference](#full-compatibility-reference) at the end. + +> [!NOTE] +> - This guide applies to upgrades from version 1.7.0 (or earlier) to 1.8.0. +> - The **Groovy script engine** remains supported in 1.8.0, allowing existing multi-line scripts, variable definitions, and Java closures to continue functioning as expected. + +--- + +## Top 6 High-Frequency Syntax and Behavioral Changes + +Among existing query scripts, the following 6 changes are the most common. **Failure to update these may cause query errors or silently return empty results.** + +### 1. `has(key, traversal)` Overload Removed (High Risk: Silent Empty Results) + +* **Impact**: + In TinkerPop 3.8.0, the `has(String, Traversal)` and `has(T, Traversal)` overloads were removed. + In the Groovy script engine, legacy code will not throw a compilation error; instead, it **silently falls back to `has(String, Object)`**, comparing the anonymous traversal object itself against vertex/edge properties. In practice, this **silently yields 0 results / empty sets**! +* **Legacy Query**: + ```groovy + // Broken in 3.8: will not throw an error, but silently returns 0 results + g.V().has('age', __.is(gt(30))) + g.V().has(T.label, __.is('person')) + ``` +* **Recommended Rewrite**: + ```groovy + // For simple scalar/predicate checks, pass predicates directly + g.V().has('age', gt(30)) + g.V().hasLabel('person') + g.V().hasId('v-1') + + // If passing property values into child traversals for complex filtering, use filter() + g.V().filter(__.values('age').is(gt(30))) + ``` + +--- + +### 2. `store()` Removed & `aggregate()` Scope Overload Removed + +* **Impact**: + - The `store('x')` step, previously used for lazy side-effect collection, has been completely removed (`No signature of method: store()`). + - The `aggregate(Scope, 'x')` overload with an explicit `Scope` (both `local` and `global`) has also been removed. +* **Legacy Query**: + ```groovy + // Broken: store step removed + g.V().store('x').by('age').cap('x') + + // Broken: aggregate(Scope, ...) overload removed + g.V().aggregate(local, 'x') + g.V().aggregate(global, 'x') + ``` +* **Recommended Rewrite**: + ```groovy + // 1. Eager global collection (formerly global aggregate): use aggregate('x') directly + g.V().aggregate('x').by('age').cap('x') + + // 2. Per-object / lazy collection (formerly store or local aggregate): wrap in local() + g.V().local(__.aggregate('x').by('age')).cap('x') + ``` + +--- + +### 3. Step `none()` Renamed to `discard()` + +* **Impact**: + The parameterless `none()` step was originally used to discard all incoming traversers (e.g., at the end of `choose()` or `coalesce()` branches). In 3.8.0, this step is renamed to **`discard()`**. + Meanwhile, 3.8 introduces a new collection predicate step `none(P)` (checking if no elements in a collection match predicate P). Calling parameterless `none()` in 3.8 triggers argument errors. +* **Recommended Rewrite**: + ```groovy + // Legacy: + g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.none()) // Error + + // Rewritten: use discard() + g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) + ``` + +--- + +### 4. Strict Behavior for Missing Properties in `by()` + +* **Impact**: + TinkerPop 3.6+ unified missing value handling across `by()` modulators (removing previous default-null behaviors). In 3.8.1, when a property referenced by `by()` does not exist: + 1. **Ordering `order().by('age')`**: Vertices missing `age` are **immediately filtered out** (previously they might sort first/last). + 2. **Projection `project('name', 'age').by('name').by('age')`**: If `age` is missing, the returned Map **will not contain the `age` key at all** (previously returned `age: null`). + 3. **Path `path().by('age')`**: If any vertex along the path misses `age`, the **entire path is dropped**. +* **Recommended Rewrite**: + If your application requires preserving elements with explicit defaults (e.g., `null`), use `coalesce()` inside `by()`: + ```groovy + // Retain key 'age' with null when missing + g.V().project('name', 'age') + .by('name') + .by(__.coalesce(__.values('age'), __.constant(null))) + + // Provide a typed default for sorting missing fields + g.V().order().by(__.coalesce(__.values('age'), __.constant(-1)), desc) + ``` + +--- + +### 5. `choose()` Semantics Alignment + +* **Impact**: + - **Single Branch Execution**: When multiple `option()` conditions match simultaneously, 3.8 **executes only the first matching branch** (legacy versions might execute all matching branches). + - **Default Pass-Through**: If the choice child traversal yields no values (e.g., property missing) or no `option()` matches, 3.8 **passes the input element through unchanged** by default (legacy versions often filtered it out). +* **Recommended Rewrite**: + - To execute multiple matching branches, rewrite using `union()` combined with `filter()`. + - To filter out elements when no option matches or property is missing, explicitly supply `Pick.none` and `Pick.unproductive` branches: + ```groovy + // Discard unmatched and missing-property inputs + g.V().choose(__.values('age')) + .option(gt(30), __.values('name')) + .option(Pick.none, __.discard()) + .option(Pick.unproductive, __.discard()) + ``` + +--- + +### 6. Date Types and Time Difference Units + +* **Impact**: + - **Return Type**: Date steps such as `datetime()` and `dateAdd()` now return **`java.time.OffsetDateTime`** instead of `java.util.Date`. + - **Unit Change in `dateDiff()`**: The difference between two dates is now returned in **milliseconds** instead of seconds (e.g., 1 day difference is `86400000` ms instead of `86400` s). +* **Recommended Rewrite**: + - Update Java clients to expect `OffsetDateTime`; convert to `java.util.Date` via `Date.from(offsetDateTime.toInstant())` only if strictly required. + - Review all TTL checks and date comparisons that use `dateDiff()`. Adjust multipliers or divide by 1000: + ```groovy + // Convert dateDiff milliseconds to seconds + g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z')) + .math('_ / 1000').asNumber(GType.LONG) + ``` + +--- + +## Server Configuration and Client Compatibility + +### 1. Serializer Class Names and Package Migration +In `conf/gremlin-server.yaml`, serializer classes moved from `gremlin-driver` to `gremlin-util`. **You must update serializer package names in the configuration, as legacy class names will cause ClassNotFoundException**: + +| Legacy Class (`driver.ser.*`) | 1.8.0 Class (`util.ser.*`) | Notes | +|---|---|---| +| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | Recommended default binary serializer | +| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | Retains untyped JSON (do not just remove `d0`, which becomes typed) | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | Standard Typed GraphSON V3 | +{.td-table--wide} + +### 2. Can HugeGraph Client 1.5.0 Continue to Work? +* **Verdict**: **Yes**. +* HugeGraph Server 1.8.0 provides backward-compatible adapters (graph alias mapping and legacy auth path redirection). Applications using `hugegraph-client:1.5.0` can continue standard CRUD, schema management, and REST operations without forced SDK upgrades. +* **Important Note**: Although Client 1.5.0 connects successfully, **all submitted Gremlin script strings are executed on the 3.8.1 server engine**. Therefore, Gremlin queries constructed in your code must comply with the 3.8 rules described above. + +--- + +## Full Compatibility Reference + +### Appendix 1: Writes & Upsert (`mergeV` / `mergeE`) +- **M01**: `onCreate` property maps strictly inherit the search match map. Conflicting keys cannot overwrite matched properties. +- **M02**: `mergeE` no longer implicitly binds incoming/outgoing vertices from upstream traversers; specify `Direction.OUT` and `Direction.IN` in the map or use explicit options. +- **M03**: Conflicting `onCreate` / `onMatch` maps are validated during construction rather than deferred to runtime execution. +- **M04**: In 3.8, child traversers in `onMatch` receive the matched Element object rather than the original input Map. Preserve input map references prior to merge with `.as('input')` and reference with `select('input')`. + +### Appendix 2: Advanced Traversal Steps & Collections +- **B07 (`local()` unpacks bulk)**: Traversers with bulk counters are expanded into individual items when entering `local()` child traversals. Use `groupCount()` for frequency analysis. +- **B09 (`range(local)` collection unpacking)**: Slicing a single item from a list (e.g., `limit(local, 1)`) consistently returns a Collection wrapper (`[item]`). Append `.unfold()` if a scalar is needed. +- **B11 (`sum()` return type)**: Summing integer streams without overflow may return `Integer` instead of `Long`. Clients should accept `Number`. +- **B14 (`split('')`)**: Splitting with an empty separator returns a list of individual characters. +- **B15 (`asString()` on null)**: `asString()` throws an `IllegalArgumentException` on null inputs. + +### Appendix 3: GLV Client Variations +- **Python**: Avoids Python keyword conflicts by appending an underscore to step names (`filter_()`, `id_()`, `range_()`, `max_()`). +- **JavaScript**: Set collections are returned as native ECMAScript `Set` instances (use `.size` and `.has()`). Deprecated `connectOnStartup` option removed; call `await connection.open()`. +- **.NET**: `byte` values serialize strictly as signed bytes (`sbyte`). +- **Go**: BigDecimal/BigInt aligned; always inspect errors on `Next()`. + +### Appendix 4: Network Protocols & Serializer Guardrails +- **C03 (OLTP element properties)**: Remote OLTP queries return elements with full properties by default rather than reference tokens only. Use `project()` or `valueMap()` to restrict payload sizes when necessary. +- **C06 (GraphSON payload limits)**: Added guardrails for max number length (10,000), max string length (20,000,000), and max nesting depth (1,000). + +### Appendix 5: HugeGraph Feature Capabilities +- **Meta-Properties Unsupported**: HugeGraph strictly follows its native schema design and does not support TinkerPop meta-properties (properties on properties). Writing property metadata in 1.8.0 will be **explicitly rejected**. +- **GraphComputer Boundaries**: `supportsComputer()` remains `false`. GraphComputer-dependent steps (e.g., `pageRank()`, `peerPressure()`) cannot run directly on the OLTP engine. Use HugeGraph algorithms REST API or Vermeer. +- **Uniform List Features**: `supportsUniformListValues()` returns `false`; property lists remain supported via HugeGraph schema (`valueList()`). diff --git a/content/en/docs/introduction/_index.md b/content/en/docs/introduction/_index.md index 4c0ff5e61c..245aae811f 100644 --- a/content/en/docs/introduction/_index.md +++ b/content/en/docs/introduction/_index.md @@ -43,7 +43,7 @@ HugeGraph Server is the OLTP engine and service entry point for the graph databa - **Query languages**: Supports Gremlin (TinkerPop 3) and Cypher (OpenCypher) - **REST API**: Provides endpoints for schemas, graph data, queries, tasks, and operations - **Indexes and queries**: Supports exact, range, and compound-condition queries -- **Storage backends**: Versions 1.7.0 through `master` primarily support RocksDB (standalone), HStore (distributed), and HBase +- **Storage backends**: Supports RocksDB (recommended for standalone), HStore (recommended for distributed), and HBase (legacy backends such as Cassandra, MySQL, and PostgreSQL were deprecated starting in 1.7.0) The main modules include `hugegraph-core`, the storage backend modules, and `hugegraph-api`. Core implements the graph model, transactions, and query logic; backend modules connect to specific storage systems; and the API module provides HTTP access. Current REST resource paths include the graph space and graph name, for example: diff --git a/content/en/docs/language/hugegraph-gremlin.md b/content/en/docs/language/hugegraph-gremlin.md index 25fe537f38..82b6efd4ff 100644 --- a/content/en/docs/language/hugegraph-gremlin.md +++ b/content/en/docs/language/hugegraph-gremlin.md @@ -10,6 +10,10 @@ HugeGraph supports [Gremlin](https://tinkerpop.apache.org/gremlin.html), a graph Gremlin can be used to create entities (Vertex and Edge) of a graph, modify the properties of entities, and delete entities. More importantly, it can be used to perform graph querying and analysis operations. +> [!NOTE] +> **Version & Migration Note**: HugeGraph 1.8.0 upgrades its underlying TinkerPop engine to **3.8.1** (along with Java 17 and Groovy 4.0.25). +> Certain legacy syntax patterns (e.g., `store()`, `has(key, traversal)`, and scoped `aggregate()`) have been deprecated or modified. See the [1.8 Gremlin & TinkerPop Migration Guide](../guides/gremlin-migration-3.8) for details. + ### TinkerPop Features HugeGraph implements the TinkerPop framework, but not all TinkerPop features are implemented. @@ -80,7 +84,7 @@ The table below lists the support status of various TinkerPop features in HugeGr | SerializableValues | | false | | StringArrayValues | | false | | StringValues | | true | -| UniformListValues | Supports setting of a {@code List} value. The assumption is that the {@code List} can contain arbitrary serializable values that may or may not be defined as a feature itself. As this{@code List} is "uniform" it must contain objects of the same type. | true | +| UniformListValues | Supports setting of a {@code List} value. The assumption is that the {@code List} can contain arbitrary serializable values that may or may not be defined as a feature itself. As this{@code List} is "uniform" it must contain objects of the same type. | false (supported via Schema valueList()) | ### Gremlin Steps @@ -96,7 +100,9 @@ HugeGraph supports all steps of Gremlin. For complete reference information abou | coalesce | Returns the first traversal that returns a result. | [coalesce step](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) | | constant | Returns a constant value. Used in conjunction with coalesce. | [constant step](http://tinkerpop.apache.org/docs/current/reference/#constant-step) | | count | Returns a count from the traversal. | [count step](http://tinkerpop.apache.org/docs/current/reference/#count-step) | +| datetime | Creates a datetime object or retrieves current server time (returns `OffsetDateTime` in 1.8.0). | [datetime step](http://tinkerpop.apache.org/docs/current/reference/#datetime-step) | | dedup | Returns values with duplicates removed. | [dedup step](http://tinkerpop.apache.org/docs/current/reference/#dedup-step) | +| discard | Discards all current traversers (replaces parameterless `none()` in 1.8.0). | [discard step](http://tinkerpop.apache.org/docs/current/reference/#discard-step) | | drop | Discards a value (vertex/edge). | [drop step](http://tinkerpop.apache.org/docs/current/reference/#drop-step) | | fold | Acts as a barrier for computing aggregated values from results. | [fold step](http://tinkerpop.apache.org/docs/current/reference/#fold-step) | | group | Groups values based on specified labels. | [group step](http://tinkerpop.apache.org/docs/current/reference/#group-step) | @@ -116,7 +122,8 @@ HugeGraph supports all steps of Gremlin. For complete reference information abou | repeat | Repeats a step a specified number of times. Used for looping. | [repeat step](http://tinkerpop.apache.org/docs/current/reference/#repeat-step) | | sample | Used to sample results returned by the traversal. | [sample step](http://tinkerpop.apache.org/docs/current/reference/#sample-step) | | select | Used to project the results returned by the traversal. | [select step](http://tinkerpop.apache.org/docs/current/reference/#select-step) | -| store | This step is used for non-blocking aggregation of results returned by traversal | [store step](http://tinkerpop.apache.org/docs/current/reference/#store-step) | +| mergeV | Matches vertices by property; updates if present, creates if absent (standard upsert). | [mergeV step](http://tinkerpop.apache.org/docs/current/reference/#mergevertex-step) | +| mergeE | Matches edges by property and endpoints; updates if present, creates if absent (standard upsert). | [mergeE step](http://tinkerpop.apache.org/docs/current/reference/#mergeedge-step) | | tree | Aggregate the paths in vertices into a tree. | [tree step](http://tinkerpop.apache.org/docs/current/reference/#tree-step) | | unfold | Unfolds an iterator as a step. | [unfold step](http://tinkerpop.apache.org/docs/current/reference/#unfold-step) | | union | Merge the results returned by multiple traversals. | [union step](http://tinkerpop.apache.org/docs/current/reference/#union-step) | diff --git a/content/en/docs/quickstart/hugegraph/hugegraph-server.md b/content/en/docs/quickstart/hugegraph/hugegraph-server.md index f1c899be91..b3fe57b3f9 100644 --- a/content/en/docs/quickstart/hugegraph/hugegraph-server.md +++ b/content/en/docs/quickstart/hugegraph/hugegraph-server.md @@ -15,7 +15,7 @@ aliases: The `hugegraph-server` module contains `hugegraph-core`, `hugegraph-api`, `hugegraph-dist`, and storage adapters. Core implements the property graph model, transactions, and TinkerPop interfaces. API provides the HTTP service and delegates client requests to Core. Graph data is stored in RocksDB (the default standalone backend), HStore (distributed), or HBase. > [!WARNING] -> **Version scope**: Download examples use the ASF HugeGraph 1.7.0 release. Source builds, configuration defaults, and startup behavior follow `apache/hugegraph` master. A master build is not an ASF release artifact, even if its version number matches a release. This guide covers RocksDB, HStore, and HBase; see [1.5.x documentation](https://github.com/apache/hugegraph-doc/blob/release-1.5.0/content/en/docs/quickstart/hugegraph/hugegraph-server.md) for other legacy backends. +> **Version scope**: This guide distinguishes between official releases and the development master branch. For official installations, use official release archives (such as 1.7.0 or the upcoming 1.8.0). Source builds, default configurations, and startup behaviors follow the `apache/hugegraph` master branch (currently targeting 1.8.0). A master build is not an ASF release artifact, even if its version number matches a release. Supported storage backends include RocksDB, HStore, and HBase; see [1.5.x documentation](https://github.com/apache/hugegraph-doc/blob/release-1.5.0/content/en/docs/quickstart/hugegraph/hugegraph-server.md) for deprecated legacy backends. > Naming: `HugeGraph` means the overall project or main repository, `hugegraph-server` is its Server module, and `HugeGraphServer` is the Java service class. Server below means the running graph database service. @@ -95,7 +95,8 @@ serializer: ``` > [!TIP] -> For complete client configuration and migration details, see the +> For complete Gremlin syntax rewrites, compatibility requirements, and reference tables, see the +> [1.8 Gremlin & TinkerPop Migration Guide](../../guides/gremlin-migration-3.8). Additional runtime details are in the > [server runtime documentation](https://github.com/apache/hugegraph/blob/master/docs/server-runtime.md). ## 3 Deploy From 0cc3ffbef7e465d313627f011d2d080d7fd04c74 Mon Sep 17 00:00:00 2001 From: imbajin Date: Tue, 20 Oct 2026 03:32:49 +0800 Subject: [PATCH 2/4] docs: address review comments on Gremlin 1.8 compatibility and migration guide --- .../hugegraph-1.8.0-release-notes.md | 6 +- .../cn/docs/guides/gremlin-migration-3.8.md | 75 ++++++++++------ content/cn/docs/introduction/_index.md | 2 +- content/cn/docs/language/hugegraph-gremlin.md | 2 +- .../hugegraph-1.8.0-release-notes.md | 7 +- .../en/docs/guides/gremlin-migration-3.8.md | 85 +++++++++++++------ content/en/docs/introduction/_index.md | 3 +- content/en/docs/language/hugegraph-gremlin.md | 2 +- 8 files changed, 118 insertions(+), 64 deletions(-) diff --git a/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md b/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md index 66031305a7..277b8ab975 100644 --- a/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md +++ b/content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md @@ -19,14 +19,14 @@ weight: 1 - **无参 `none()` 更名为 `discard()`**:丢弃输入遍历必须使用 `discard()`(避免与新集合过滤 `none(P)` 冲突)。 - **`by()` 缺失属性严检**:缺失属性在 `order().by()` 下直接过滤顶点,在 `project().by()` 下不再返回该 key,在 `path().by()` 下直接过滤路径;需保留缺失字段请在 `by()` 中显式使用 `coalesce()` 补默认值。 - **`choose()` 分支语义收敛**:多条件重叠仅执行首个匹配分支;无匹配或属性缺失默认原样放行穿透(需过滤请显式加 `Pick.none` / `Pick.unproductive` 分支配合 `discard()`)。 -- **日期类型与单位变更**:日期操作产出由 `java.util.Date` 转向 `OffsetDateTime`;`dateDiff()` 差值单位从**秒变为毫秒**。 > 完整改写代码对照与全量细则速查表请参阅:[HugeGraph 1.8.0 Gremlin 迁移与兼容性指南](../guides/gremlin-migration-3.8)。 #### 2. 服务端配置与客户端兼容 - **Serializer 类名迁移**:`conf/gremlin-server.yaml` 中序列化器包路径由 `org.apache.tinkerpop.gremlin.driver.ser.*` 迁移至 `org.apache.tinkerpop.gremlin.util.ser.*`。 - **HugeGraph Client 1.5.0**:服务端提供向后兼容适配,1.5.0 客户端无需换包可正常连通 1.8.0 服务端;但客户端拼接的 Gremlin 脚本需按 3.8 语法规范调整。 -- **移除内置 GPL word 分词器**:统一使用 IK、SmartCN 等合规分词器。 +- **不再默认捆绑 GPL word 分词器**:因开源协议合规,默认发行包不再捆绑 GPLv3 的 `word-1.3.jar`。配置了 `search.text_analyzer=word` 的图仍受支持, + 只需将 `word-1.3.jar` 放入 Server 的 `lib/` 目录即可正常使用;亦可切换为内置的 IK 或 SmartCN(注意切换分词器后需重建已有搜索索引)。 --- @@ -37,6 +37,6 @@ weight: 1 - **BREAKING CHANGE**: Shared foundation module migration (`hugegraph-struct`) #### Feature Changes -- Support TinkerPop 3.8 steps including `discard()`, `mergeV()`, `mergeE()`, and `datetime()` +- 支持 TinkerPop 3.8 步骤,包括 `discard()`、`mergeV()`、`mergeE()` 以及日期步骤(`datetime()`、`dateAdd()`、`dateDiff()`) - Adapt HugeSecurityManager and Groovy 4.0.25 on Java 17 - Improve count query visibility inside uncommitted transactions diff --git a/content/cn/docs/guides/gremlin-migration-3.8.md b/content/cn/docs/guides/gremlin-migration-3.8.md index 2dac113614..a4b3a4ad1c 100644 --- a/content/cn/docs/guides/gremlin-migration-3.8.md +++ b/content/cn/docs/guides/gremlin-migration-3.8.md @@ -15,9 +15,9 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 --- -## 核心重点:最常用的 6 大语法与行为变化 +## 核心重点:最常用的 5 大语法与行为变化 -在已有的业务查询中,以下 6 项改动最为高频,**若不改写可能直接导致查询报错或静默返回空结果(查询不到数据)**,请优先重点排查。 +在已有的业务查询中,以下 5 项改动最为高频,**若不改写可能直接导致查询报错或静默返回空结果(查询不到数据)**,请优先重点排查。 ### 1. `has(key, traversal)` 重载删除(高危:静默返回空结果) @@ -71,14 +71,19 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 ### 3. 丢弃输入步骤 `none()` 更名为 `discard()` * **影响说明**: - 无参的 `none()` 原本用于丢弃流中的所有输入(如在 `choose()` 或 `coalesce()` 结尾丢弃未匹配元素)。3.8.0 中该操作更名为 **`discard()`**。 - 3.8 同时引入了新的集合谓词步骤 `none(P)`(用于检查集合是否没有元素满足条件)。若在旧代码中写无参的 `none()`,极易误命中或抛出参数异常。 + 在 TinkerPop 3.5.1 中,`none()` 为 traversal 步骤,用于丢弃流中输入(如 `g.V().hasLabel('person').none()` 返回 `[]`)。 + 3.8.1 中该操作更名为 **`discard()`**。 + 同时 3.8 引入了新的集合谓词步骤 `none(P)`(用于检查集合是否没有元素满足条件)。若在 3.8.1 中直接调用无参 `none()`,会立即抛出异常: + `IllegalArgumentException: Input predicate to none step can't be null.` * **推荐改写方案**: ```groovy - // 旧写法:丢弃未匹配元素 - g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.none()) // 错误 + // 旧写法(3.5.1 下执行返回 []): + g.V().hasLabel('person').none() // 新写法:统一使用 discard() + g.V().hasLabel('person').discard() + + // 在 choose() 或分支中丢弃未匹配元素: g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) ``` @@ -108,8 +113,11 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 ### 5. 分支条件 `choose()` 语义收敛 * **影响说明**: + - **缺失属性处理**:当选择子遍历依赖的属性缺失时,TinkerPop 3.5.1 会直接抛出异常: + `IllegalArgumentException: The provided traverser does not map to a value: v[3]->[PropertiesStep([age],value)]`。 + 在 3.8.1 中,缺少对应属性的元素不再报错,而是默认原样放行穿透。 - **单分支执行**:当多个 `option()` 条件同时命中时,旧版可能会把多个匹配分支全部执行;新版**只执行第一个命中的分支**。 - - **默认放行机制**:如果选择子遍历不产值(例如没有对应的属性),或没有任何一个 `option()` 匹配,新版**默认将输入元素原样向下游放行**(旧版通常会过滤掉)。 + - **默认放行机制**:如果没有任何一个 `option()` 匹配,新版**默认将输入元素原样向下游放行**(3.5.1 则会过滤掉)。 * **推荐改写方案**: - 如需在多个条件同时命中时全部执行,请使用 `union()` 配合 `filter()`。 - 如需在无匹配或属性缺失时将元素过滤抛弃,需显式声明 `Pick.none` 与 `Pick.unproductive` 分支: @@ -123,16 +131,21 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 --- -### 6. 日期类型与时间差单位变化 +## 1.8 新增步骤与内置函数(TinkerPop 3.8) -* **影响说明**: - - **类型转向**:`datetime()`、`dateAdd()` 等日期操作的默认返回类型从 `java.util.Date` 转向 **`java.time.OffsetDateTime`**。 - - **单位由秒变毫秒**:`dateDiff()` 计算两个日期的差值,结果单位**从秒(s)改为毫秒(ms)**(例如相隔 1 天的结果由 `86400` 变为 `86400000`)。 -* **推荐改写方案**: - - Java 客户端与 SDK 应使用 `OffsetDateTime` 接收时间对象;若确需原生 `java.util.Date`,可通过 `Date.from(offsetDateTime.toInstant())` 进行转换。 - - 检查业务代码中所有涉及 `dateDiff()` 的比较阈值、TTL 策略及时间报表,将原先基于秒的计算乘以 1000 或显式除以 1000: +TinkerPop 3.8 引入了原生日期操作函数与步骤,这些能力在 3.5.1(HugeGraph 1.7.0)中并不存在: + +### 日期步骤(`datetime()`、`dateAdd()`、`dateDiff()`) + +- **`datetime()`**:构造日期时间对象或取得服务器当前时间。在 3.8 中返回 **`java.time.OffsetDateTime`**(如 `datetime('2026-10-19T00:00:00Z')`)。 +- **`dateAdd()`**:对日期进行加减运算。 +- **`dateDiff()`**:计算两个日期的差值,返回差值的**毫秒数**(例如相隔 1 天的结果为 `86400000` ms)。 +- **代码示例**: ```groovy - // 将 dateDiff 毫秒转换为秒 + // 获取当前时间 OffsetDateTime + g.inject(datetime()) + + // 计算日期毫秒差并转换为秒 g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z')) .math('_ / 1000').asNumber(GType.LONG) ``` @@ -141,14 +154,23 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 ## 服务端配置与客户端连接兼容 -### 1. 服务端 Serializer 类名与包名迁移 -在 `conf/gremlin-server.yaml` 中,TinkerPop 3.8 将序列化器从 `gremlin-driver` 包分离到了 `gremlin-util` 包中。**必须更新 YAML 中的全限定类名,旧类名不是兼容别名,否则启动时将报 ClassNotFoundException**: +### 1. `conf/gremlin-server.yaml` 序列化器配置 + +在 TinkerPop 3.8 中,序列化器从 `gremlin-driver`(`org.apache.tinkerpop.gremlin.driver.ser.*`)包迁移到了 `gremlin-util`(`org.apache.tinkerpop.gremlin.util.ser.*`)包。 + +> [!IMPORTANT] +> **请勿直接复制 1.7.0 的 `gremlin-server.yaml` 并仅替换类名!** +> 推荐直接使用 HugeGraph 1.8.0 发行包自带的 `conf/gremlin-server.yaml`,再将自定义端口、认证等配置合并进去。 +> HugeGraph 需要专用的 Builder 与 Registry:GraphBinary 必须配置 `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder` +> 才能序列化 HugeGraph 的 `Id`、Schema、`Blob` 与枚举类型(否则会抛出 `IOException: Serializer for type ... not found`); +> 无类型 GraphSON V1 需要添加 `org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry`。 -| 旧配置类名 (`driver.ser.*`) | 1.8.0 对应类名 (`util.ser.*`) | 说明 | -|---|---|---| -| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | 推荐,默认高效二进制协议 | -| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | 保持无类型 JSON(不可只去掉 d0,否则会变成 typed) | -| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | 标准 Typed GraphSON V3 | +| 旧配置类名 (`driver.ser.*`) | 1.8.0 对应类名 (`util.ser.*`) | 所需 Builder / Registry | 说明 | +|---|---|---|---| +| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder`
`ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 推荐,默认高效二进制协议 | +| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry, org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry]` | 保持无类型 GraphSON V1 | +| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 无类型 GraphSON V2 | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 标准 Typed GraphSON V3 | {.td-table--wide} ### 2. HugeGraph Client 1.5.0 能否平滑使用? @@ -163,7 +185,7 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 除上述高频变化外,TinkerPop 3.5.1 → 3.8.1 还包含若干深层优化与边缘语义调整。如遇特定场景异常,请查阅下表对应项: ### 附录 1:写入与 Upsert(`mergeV` / `mergeE`) -从 3.6.0 开始推荐使用标准的 `mergeV()` 与 `mergeE()` 执行图数据 Upsert 操作: +`mergeV()` 与 `mergeE()` 是 TinkerPop 3.8(3.5.1 中不存在)推荐的标准图数据 Upsert 操作: - **M01**: `onCreate` 的属性 Map 严格继承主匹配 Map,不允许用冲突值覆盖主匹配条件(如匹配条件是 `name: 'A'`,`onCreate` 不能设 `name: 'B'`)。 - **M02**: `mergeE` 不再隐式拿上游顶点填补端点,必须在 Map 中指明 `(Direction.OUT)` 与 `(Direction.IN)`,或使用 `option(Merge.outV, ...)` 显式绑定。 - **M03**: `onMatch` 与 `onCreate` 的属性冲突在构造期就会被严格校验,而非等到运行时才报错。 @@ -173,8 +195,8 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 - **B07 (`local()` 拆 bulk)**:带 bulk 计数的 Traverser 经过 `local()` 子遍历时会被展开为单个对象处理。若需统计频次,建议使用 `groupCount()`。 - **B09 (`range(local)` 集合解包)**:对列表截取单元素(如 `limit(local, 1)`),新版始终返回 Collection 包装(如 `[1]`),若业务必须获取标量,请在后续追加 `.unfold()`。 - **B11 (`sum()` 返回类型)**:整数流的 `sum()` 结果可能直接返回 Integer 而不是 Long(若无溢出),建议 Java 端统一使用 `Number` 接收。 -- **B14 (`split('')`)**:空字符串分隔符在 3.8 中将拆分为单字符列表(如 `'abc'` 拆分为 `['a','b','c']`)。 -- **B15 (`asString()` 遇 null)**:`asString()` 接收到 null 时会抛出异常,如需兼容 null 请配合 `choose()` 显式处理。 +- **B14 (`split()` 步骤)**:TinkerPop 3.8 新增步骤。空字符串分隔符在 3.8 中将拆分为单字符列表(如 `'abc'` 拆分为 `['a','b','c']`)。 +- **B15 (`asString()` 步骤)**:TinkerPop 3.8 新增步骤。`asString()` 接收到 null 时会抛出 `IllegalArgumentException`,如需兼容 null 请配合 `choose()` 显式处理。 ### 附录 3:多语言客户端差异(GLV) - **Python**:步骤名避免与 Python 关键字冲突,全面使用下划线后缀(如 `filter_()`、`id_()`、`range_()`、`max_()` 等),推荐使用 snake_case(如 `has_label`)。 @@ -187,6 +209,7 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 - **C06 (GraphSON 载荷安全限制)**:新增数字长度(默认 10,000)、字符串长度(默认 20,000,000)与嵌套深度(默认 1,000)反序列化上限,避免深层 JSON 导致 OOM。 ### 附录 5:HugeGraph 适配与能力边界 -- **不支持 Meta-Properties**:HugeGraph 严格遵循自有 Schema 体系,不支持 TinkerPop 的属性元数据(属性上的属性)。在 1.8.0 中若向属性写入 metadata 将被**显式拒绝**,不再隐式退化。 +- **元属性保持不支持(Unchanged)**:HugeGraph 严格遵循自有 Schema 体系,历来不支持 TinkerPop 的属性元数据(属性上的属性)。 + 向顶点属性写入 metadata 始终会抛出 `VertexProperty.Exceptions.metaPropertiesNotSupported()` 或 `NotSupportException("nested property")`,1.8.0 行为与历史版本完全一致。 - **图计算限制**:`supportsComputer()` 仍为 `false`,依赖 `GraphComputer` 的步骤(如 `pageRank()`、`peerPressure()`)不能在 OLTP 引擎上直接执行,建议使用 HugeGraph 的专门算法 API 或 Vermeer 组件。 - **统一列表特性**:`supportsUniformListValues()` 现返回 `false`;图中的 List 属性依然由 HugeGraph 内部 Schema (`valueList()`) 提供完整支持。 diff --git a/content/cn/docs/introduction/_index.md b/content/cn/docs/introduction/_index.md index a7e97fd61f..5859427d88 100644 --- a/content/cn/docs/introduction/_index.md +++ b/content/cn/docs/introduction/_index.md @@ -43,7 +43,7 @@ HugeGraph Server 是图数据库的 OLTP 引擎和服务入口,负责属性图 - **查询语言**:支持 Gremlin(TinkerPop 3)和 Cypher(OpenCypher) - **REST API**:提供 Schema、图数据、查询、任务和运维接口 - **索引与查询**:支持精确查询、范围查询和复合条件查询 -- **存储后端**:支持 RocksDB(单机推荐)、HStore(分布式推荐)和 HBase(自 1.7.0 起已废弃 Cassandra、MySQL、PostgreSQL 等旧后端) +- **存储后端**:支持 RocksDB(单机推荐)、HStore(分布式推荐)和 HBase(Cassandra、MySQL、PostgreSQL 等历史后端已在 1.7.0 禁用并在 1.8.0 彻底移除) 主要模块包括 `hugegraph-core`、存储后端模块和 `hugegraph-api`。Core 实现图模型、事务和查询逻辑,后端模块负责连接具体存储系统,API 模块负责 HTTP 接入。当前 REST 资源路径包含图空间与图名称,例如: diff --git a/content/cn/docs/language/hugegraph-gremlin.md b/content/cn/docs/language/hugegraph-gremlin.md index 4cf760a209..18e117afc0 100644 --- a/content/cn/docs/language/hugegraph-gremlin.md +++ b/content/cn/docs/language/hugegraph-gremlin.md @@ -100,7 +100,7 @@ HugeGraph支持Gremlin的所有步骤。有关Gremlin的完整参考信息,请 | coalesce | 返回第一个返回结果的遍历 | [coalesce step](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) | | constant | 返回常量值。 与`coalesce`配合使用 | [constant step](http://tinkerpop.apache.org/docs/current/reference/#constant-step) | | count | 从遍历返回计数 | [count step](http://tinkerpop.apache.org/docs/current/reference/#count-step) | -| datetime | 构造日期时间对象或取得服务器当前时间(1.8.0 默认返回 `OffsetDateTime`) | [datetime step](http://tinkerpop.apache.org/docs/current/reference/#datetime-step) | +| datetime | 构造日期时间对象或取得服务器当前时间(1.8.0 默认返回 `OffsetDateTime`) | [datetime function](https://tinkerpop.apache.org/docs/current/reference/#gremlin-groovy-differences) | | dedup | 返回已删除重复内容的值 | [dedup step](http://tinkerpop.apache.org/docs/current/reference/#dedup-step) | | discard | 丢弃流中当前输入(1.8.0 替代原无参 `none()`) | [discard step](http://tinkerpop.apache.org/docs/current/reference/#discard-step) | | drop | 丢弃值(顶点/边缘) | [drop step](http://tinkerpop.apache.org/docs/current/reference/#drop-step) | diff --git a/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md b/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md index f416915972..8b34e1647d 100644 --- a/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md +++ b/content/en/docs/changelog/hugegraph-1.8.0-release-notes.md @@ -19,14 +19,15 @@ weight: 1 - **Step `none()` renamed to `discard()`**: Discarding incoming traversers must now use `discard()` (avoids collision with new collection predicate `none(P)`). - **Strict `by()` behavior on missing properties**: Vertices missing properties are dropped in `order().by()`; keys are omitted from maps in `project().by()`; paths are discarded in `path().by()`. Wrap with `coalesce()` to provide explicit defaults if preservation is needed. - **`choose()` semantics alignment**: Executes only the first matching branch when conditions overlap; passes elements through unchanged by default when no branch matches or values are absent. -- **Date types & unit changes**: Date operations return `OffsetDateTime` instead of `java.util.Date`; `dateDiff()` results are in **milliseconds instead of seconds**. > For comprehensive query comparison examples and the full migration checklist, see the [HugeGraph 1.8.0 Gremlin Migration & Compatibility Guide](../guides/gremlin-migration-3.8). #### 2. Server Configuration & Client Compatibility - **Serializer class names**: Serializer packages in `conf/gremlin-server.yaml` moved from `org.apache.tinkerpop.gremlin.driver.ser.*` to `org.apache.tinkerpop.gremlin.util.ser.*`. - **HugeGraph Client 1.5.0**: Supported via server-side backward-compatibility adapters; however, Gremlin query strings must follow TinkerPop 3.8 syntax. -- **GPL word analyzer removed**: Use IK, SmartCN, or other compliant analyzers. +- **GPL word analyzer no longer bundled**: `word-1.3.jar` is no longer bundled by default due to license compliance. + Graphs configured with `search.text_analyzer=word` remain supported once `word-1.3.jar` is placed in Server's `lib/` directory. + Alternatively, switch to IK or SmartCN (note that switching analyzers requires rebuilding search indexes). --- @@ -37,6 +38,6 @@ weight: 1 - **BREAKING CHANGE**: Shared foundation module migration (`hugegraph-struct`) #### Feature Changes -- Support TinkerPop 3.8 steps including `discard()`, `mergeV()`, `mergeE()`, and `datetime()` +- Support TinkerPop 3.8 steps including `discard()`, `mergeV()`, `mergeE()`, and date steps (`datetime()`, `dateAdd()`, `dateDiff()`) - Adapt HugeSecurityManager and Groovy 4.0.25 on Java 17 - Improve count query visibility inside uncommitted transactions diff --git a/content/en/docs/guides/gremlin-migration-3.8.md b/content/en/docs/guides/gremlin-migration-3.8.md index fdfa1145fb..80f3239ac6 100644 --- a/content/en/docs/guides/gremlin-migration-3.8.md +++ b/content/en/docs/guides/gremlin-migration-3.8.md @@ -15,9 +15,9 @@ While bringing substantial performance optimizations and specification alignment --- -## Top 6 High-Frequency Syntax and Behavioral Changes +## Top 5 High-Frequency Syntax and Behavioral Changes -Among existing query scripts, the following 6 changes are the most common. **Failure to update these may cause query errors or silently return empty results.** +Among existing query scripts, the following 5 changes are the most common. **Failure to update these may cause query errors or silently return empty results.** ### 1. `has(key, traversal)` Overload Removed (High Risk: Silent Empty Results) @@ -71,14 +71,20 @@ Among existing query scripts, the following 6 changes are the most common. **Fai ### 3. Step `none()` Renamed to `discard()` * **Impact**: - The parameterless `none()` step was originally used to discard all incoming traversers (e.g., at the end of `choose()` or `coalesce()` branches). In 3.8.0, this step is renamed to **`discard()`**. - Meanwhile, 3.8 introduces a new collection predicate step `none(P)` (checking if no elements in a collection match predicate P). Calling parameterless `none()` in 3.8 triggers argument errors. + In TinkerPop 3.5.1, `none()` was a traversal step used to discard all incoming traversers (e.g., `g.V().hasLabel('person').none()`, which returned `[]`). + In 3.8.1, this step has been renamed to **`discard()`**. + Meanwhile, 3.8 introduces a new collection predicate step `none(P)` (checking if no elements in a collection match predicate P). Invoking parameterless + `none()` in 3.8.1 fails immediately with: + `IllegalArgumentException: Input predicate to none step can't be null.` * **Recommended Rewrite**: ```groovy - // Legacy: - g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.none()) // Error + // Legacy (runs on 3.5.1, returning []): + g.V().hasLabel('person').none() - // Rewritten: use discard() + // Rewritten for 3.8: use discard() to discard traversers + g.V().hasLabel('person').discard() + + // Discarding unhandled inputs in choose() branches: g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) ``` @@ -108,8 +114,11 @@ Among existing query scripts, the following 6 changes are the most common. **Fai ### 5. `choose()` Semantics Alignment * **Impact**: - - **Single Branch Execution**: When multiple `option()` conditions match simultaneously, 3.8 **executes only the first matching branch** (legacy versions might execute all matching branches). - - **Default Pass-Through**: If the choice child traversal yields no values (e.g., property missing) or no `option()` matches, 3.8 **passes the input element through unchanged** by default (legacy versions often filtered it out). + - **Missing Property Handling**: When a choice child traversal evaluated an absent property on an element, TinkerPop 3.5.1 threw: + `IllegalArgumentException: The provided traverser does not map to a value: v[3]->[PropertiesStep([age],value)]`. + In 3.8.1, elements missing the target property pass through unchanged without error. + - **Single Branch Execution**: When multiple `option()` conditions match simultaneously, 3.8.1 **executes only the first matching branch** (legacy versions might execute all matching branches). + - **Default Pass-Through**: When no `option()` condition matches, 3.8.1 **passes the input element through unchanged** by default (whereas 3.5.1 filtered it out). * **Recommended Rewrite**: - To execute multiple matching branches, rewrite using `union()` combined with `filter()`. - To filter out elements when no option matches or property is missing, explicitly supply `Pick.none` and `Pick.unproductive` branches: @@ -123,16 +132,23 @@ Among existing query scripts, the following 6 changes are the most common. **Fai --- -### 6. Date Types and Time Difference Units +## New Steps & Functions in 1.8 (TinkerPop 3.8) -* **Impact**: - - **Return Type**: Date steps such as `datetime()` and `dateAdd()` now return **`java.time.OffsetDateTime`** instead of `java.util.Date`. - - **Unit Change in `dateDiff()`**: The difference between two dates is now returned in **milliseconds** instead of seconds (e.g., 1 day difference is `86400000` ms instead of `86400` s). -* **Recommended Rewrite**: - - Update Java clients to expect `OffsetDateTime`; convert to `java.util.Date` via `Date.from(offsetDateTime.toInstant())` only if strictly required. - - Review all TTL checks and date comparisons that use `dateDiff()`. Adjust multipliers or divide by 1000: +TinkerPop 3.8 introduces native date manipulation functions and steps that were not present in 3.5.1 (HugeGraph 1.7.0): + +### Date Steps (`datetime()`, `dateAdd()`, `dateDiff()`) + +- **`datetime()`**: Creates a date-time object or retrieves server time. + In 3.8, it returns **`java.time.OffsetDateTime`** (e.g., `datetime('2026-10-19T00:00:00Z')`). +- **`dateAdd()`**: Performs date arithmetic, adding a duration to a date. +- **`dateDiff()`**: Computes the difference between two date-time objects, returning the difference in **milliseconds** + (e.g., a 1-day difference yields `86400000` ms). +- **Example**: ```groovy - // Convert dateDiff milliseconds to seconds + // Current time as OffsetDateTime + g.inject(datetime()) + + // Compute difference in milliseconds, convert to seconds g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z')) .math('_ / 1000').asNumber(GType.LONG) ``` @@ -141,14 +157,24 @@ Among existing query scripts, the following 6 changes are the most common. **Fai ## Server Configuration and Client Compatibility -### 1. Serializer Class Names and Package Migration -In `conf/gremlin-server.yaml`, serializer classes moved from `gremlin-driver` to `gremlin-util`. **You must update serializer package names in the configuration, as legacy class names will cause ClassNotFoundException**: +### 1. Serializer Configuration in `conf/gremlin-server.yaml` + +In TinkerPop 3.8, serializer classes moved from `gremlin-driver` (`org.apache.tinkerpop.gremlin.driver.ser.*`) +to `gremlin-util` (`org.apache.tinkerpop.gremlin.util.ser.*`). + +> [!IMPORTANT] +> **Do not simply copy an old `gremlin-server.yaml` from 1.7.0 and edit class names.** +> Always start from the `conf/gremlin-server.yaml` bundled with HugeGraph 1.8.0 and carry over your customizations (ports, host, authenticator). +> HugeGraph requires custom serializer builders and registries: GraphBinary requires `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder` +> to serialize HugeGraph `Id`, schema, `Blob`, and enum values (otherwise failing with `IOException: Serializer for type ... not found`); +> untyped GraphSON V1 requires `org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry`. -| Legacy Class (`driver.ser.*`) | 1.8.0 Class (`util.ser.*`) | Notes | -|---|---|---| -| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | Recommended default binary serializer | -| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | Retains untyped JSON (do not just remove `d0`, which becomes typed) | -| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | Standard Typed GraphSON V3 | +| Legacy Serializer (`driver.ser.*`) | 1.8.0 Serializer (`util.ser.*`) | Required Registries / Builder | Notes | +|---|---|---|---| +| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder`
`ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Recommended default binary serializer | +| `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry, org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry]` | Untyped GraphSON V1 | +| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V2 | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V3 | {.td-table--wide} ### 2. Can HugeGraph Client 1.5.0 Continue to Work? @@ -161,17 +187,18 @@ In `conf/gremlin-server.yaml`, serializer classes moved from `gremlin-driver` to ## Full Compatibility Reference ### Appendix 1: Writes & Upsert (`mergeV` / `mergeE`) +`mergeV()` and `mergeE()` are new steps in TinkerPop 3.8 (absent in 3.5.1) for graph upserts: - **M01**: `onCreate` property maps strictly inherit the search match map. Conflicting keys cannot overwrite matched properties. - **M02**: `mergeE` no longer implicitly binds incoming/outgoing vertices from upstream traversers; specify `Direction.OUT` and `Direction.IN` in the map or use explicit options. - **M03**: Conflicting `onCreate` / `onMatch` maps are validated during construction rather than deferred to runtime execution. -- **M04**: In 3.8, child traversers in `onMatch` receive the matched Element object rather than the original input Map. Preserve input map references prior to merge with `.as('input')` and reference with `select('input')`. +- **M04**: Child traversers in `onMatch` receive the matched Element object rather than the original input Map. Preserve input map references prior to merge with `.as('input')` and reference with `select('input')`. ### Appendix 2: Advanced Traversal Steps & Collections - **B07 (`local()` unpacks bulk)**: Traversers with bulk counters are expanded into individual items when entering `local()` child traversals. Use `groupCount()` for frequency analysis. - **B09 (`range(local)` collection unpacking)**: Slicing a single item from a list (e.g., `limit(local, 1)`) consistently returns a Collection wrapper (`[item]`). Append `.unfold()` if a scalar is needed. - **B11 (`sum()` return type)**: Summing integer streams without overflow may return `Integer` instead of `Long`. Clients should accept `Number`. -- **B14 (`split('')`)**: Splitting with an empty separator returns a list of individual characters. -- **B15 (`asString()` on null)**: `asString()` throws an `IllegalArgumentException` on null inputs. +- **B14 (`split()` step)**: New step in TinkerPop 3.8. An empty string separator splits the string into individual characters. +- **B15 (`asString()` step)**: New step in TinkerPop 3.8. Throws `IllegalArgumentException` on null inputs. ### Appendix 3: GLV Client Variations - **Python**: Avoids Python keyword conflicts by appending an underscore to step names (`filter_()`, `id_()`, `range_()`, `max_()`). @@ -184,6 +211,8 @@ In `conf/gremlin-server.yaml`, serializer classes moved from `gremlin-driver` to - **C06 (GraphSON payload limits)**: Added guardrails for max number length (10,000), max string length (20,000,000), and max nesting depth (1,000). ### Appendix 5: HugeGraph Feature Capabilities -- **Meta-Properties Unsupported**: HugeGraph strictly follows its native schema design and does not support TinkerPop meta-properties (properties on properties). Writing property metadata in 1.8.0 will be **explicitly rejected**. +- **Meta-Properties Unchanged (Unsupported)**: HugeGraph has never supported TinkerPop meta-properties (properties on properties). + Calling `property()` with key-values on a vertex property throws `VertexProperty.Exceptions.metaPropertiesNotSupported()` + or `NotSupportException("nested property")`, which remains the unchanged behavior in 1.8.0. - **GraphComputer Boundaries**: `supportsComputer()` remains `false`. GraphComputer-dependent steps (e.g., `pageRank()`, `peerPressure()`) cannot run directly on the OLTP engine. Use HugeGraph algorithms REST API or Vermeer. - **Uniform List Features**: `supportsUniformListValues()` returns `false`; property lists remain supported via HugeGraph schema (`valueList()`). diff --git a/content/en/docs/introduction/_index.md b/content/en/docs/introduction/_index.md index 245aae811f..9a5b34ed62 100644 --- a/content/en/docs/introduction/_index.md +++ b/content/en/docs/introduction/_index.md @@ -43,7 +43,8 @@ HugeGraph Server is the OLTP engine and service entry point for the graph databa - **Query languages**: Supports Gremlin (TinkerPop 3) and Cypher (OpenCypher) - **REST API**: Provides endpoints for schemas, graph data, queries, tasks, and operations - **Indexes and queries**: Supports exact, range, and compound-condition queries -- **Storage backends**: Supports RocksDB (recommended for standalone), HStore (recommended for distributed), and HBase (legacy backends such as Cassandra, MySQL, and PostgreSQL were deprecated starting in 1.7.0) +- **Storage backends**: Supports RocksDB (recommended for standalone), HStore (recommended for distributed), and HBase (legacy backends such as Cassandra, + MySQL, and PostgreSQL were disabled in 1.7.0 and removed in 1.8.0) The main modules include `hugegraph-core`, the storage backend modules, and `hugegraph-api`. Core implements the graph model, transactions, and query logic; backend modules connect to specific storage systems; and the API module provides HTTP access. Current REST resource paths include the graph space and graph name, for example: diff --git a/content/en/docs/language/hugegraph-gremlin.md b/content/en/docs/language/hugegraph-gremlin.md index 82b6efd4ff..8b9675dede 100644 --- a/content/en/docs/language/hugegraph-gremlin.md +++ b/content/en/docs/language/hugegraph-gremlin.md @@ -100,7 +100,7 @@ HugeGraph supports all steps of Gremlin. For complete reference information abou | coalesce | Returns the first traversal that returns a result. | [coalesce step](http://tinkerpop.apache.org/docs/current/reference/#coalesce-step) | | constant | Returns a constant value. Used in conjunction with coalesce. | [constant step](http://tinkerpop.apache.org/docs/current/reference/#constant-step) | | count | Returns a count from the traversal. | [count step](http://tinkerpop.apache.org/docs/current/reference/#count-step) | -| datetime | Creates a datetime object or retrieves current server time (returns `OffsetDateTime` in 1.8.0). | [datetime step](http://tinkerpop.apache.org/docs/current/reference/#datetime-step) | +| datetime | Creates a datetime object or retrieves current server time (returns `OffsetDateTime` in 1.8.0). | [datetime function](https://tinkerpop.apache.org/docs/current/reference/#gremlin-groovy-differences) | | dedup | Returns values with duplicates removed. | [dedup step](http://tinkerpop.apache.org/docs/current/reference/#dedup-step) | | discard | Discards all current traversers (replaces parameterless `none()` in 1.8.0). | [discard step](http://tinkerpop.apache.org/docs/current/reference/#discard-step) | | drop | Discards a value (vertex/edge). | [drop step](http://tinkerpop.apache.org/docs/current/reference/#drop-step) | From 2ca8d1c0188a853e75a98f6d6e8888c394fa229d Mon Sep 17 00:00:00 2001 From: contrueCT Date: Thu, 22 Oct 2026 12:48:17 +0800 Subject: [PATCH 3/4] docs: resolve PR #541 review findings on TinkerPop 3.8 and Server 1.8 compatibility --- .../hugegraph-1.7.0-release-notes.md | 2 +- .../cn/docs/guides/gremlin-migration-3.8.md | 48 ++++++++++------ content/cn/docs/language/hugegraph-gremlin.md | 2 +- .../hugegraph-1.7.0-release-notes.md | 2 +- .../en/docs/guides/gremlin-migration-3.8.md | 55 +++++++++++-------- content/en/docs/language/hugegraph-gremlin.md | 2 +- 6 files changed, 67 insertions(+), 44 deletions(-) diff --git a/content/cn/docs/changelog/hugegraph-1.7.0-release-notes.md b/content/cn/docs/changelog/hugegraph-1.7.0-release-notes.md index f0292142cd..83bdd8eedd 100644 --- a/content/cn/docs/changelog/hugegraph-1.7.0-release-notes.md +++ b/content/cn/docs/changelog/hugegraph-1.7.0-release-notes.md @@ -1,7 +1,7 @@ --- title: "HugeGraph 1.7.0 Release Notes" linkTitle: "Release-1.7.0" -weight: 1 +weight: 2 --- > WIP: This doc is under construction, please wait for the final version (BETA) diff --git a/content/cn/docs/guides/gremlin-migration-3.8.md b/content/cn/docs/guides/gremlin-migration-3.8.md index a4b3a4ad1c..365a3f554c 100644 --- a/content/cn/docs/guides/gremlin-migration-3.8.md +++ b/content/cn/docs/guides/gremlin-migration-3.8.md @@ -17,16 +17,21 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 ## 核心重点:最常用的 5 大语法与行为变化 -在已有的业务查询中,以下 5 项改动最为高频,**若不改写可能直接导致查询报错或静默返回空结果(查询不到数据)**,请优先重点排查。 +在已有的业务查询中,以下 5 项改动最为高频,**若不改写在 HugeGraph 1.8 中会直接导致执行报错**,请优先重点排查。 -### 1. `has(key, traversal)` 重载删除(高危:静默返回空结果) +### 1. `has(key, traversal)` 重载删除(高危:查询执行报错) * **影响说明**: - 在 3.8.0 中,`has(String, Traversal)` 和 `has(T, Traversal)` 重载被彻底移除。 - 在 Groovy 脚本引擎下,旧写法不会抛出编译错误,而是会**静默命中 `has(String, Object)` 重载**——即把子遍历对象本身作为属性值去图里比对,实测**直接返回 0 条结果/空结果**! + 在 TinkerPop 3.8.0 中,`has(String, Traversal)` 和 `has(T, Traversal)` 重载被彻底移除。 + 在 Groovy 脚本引擎下,旧写法会退化命中 `has(String, Object)` 重载。在 HugeGraph 1.8 中,由于图引擎将 `has()` 谓词下推至后端存储检索,并通过 `TraversalUtil.validPropertyValue()` 对属性值进行强类型校验,**会直接抛出类型不匹配异常**: + - 属性过滤如 `g.V().has('age', __.is(gt(30)))` 抛出: + `IllegalArgumentException: Invalid data type of query value '[IsStep(gt(30))]', expect INT for 'age', actual got class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal` + - 标签过滤如 `g.V().has(T.label, __.is('person'))` 抛出: + `HugeException: The label type must be number or string, but got 'class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal'` + *(注:仅在纯内存 TinkerGraph 上会静默返回空数组 `[]`,而在 HugeGraph 1.8 上会严格报错)*。 * **典型旧写法**: ```groovy - // 错误!3.8 下不会报错,但会静默返回空结果 + // 错误!在 HugeGraph 1.8 下执行将抛出 Invalid data type 异常 g.V().has('age', __.is(gt(30))) g.V().has(T.label, __.is('person')) ``` @@ -46,7 +51,7 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 ### 2. `store()` 彻底删除 & `aggregate()` Scope 重载移除 * **影响说明**: - - 旧版中用于惰性边走边收集副作用的 `store('x')` 步骤已被完全删除,直接报错 `No signature of method: store()`。 + - 旧版中用于惰性边走边收集副作用的 `store('x')` 步骤已被完全删除,在 3.8.1 中直接报错 `MissingMethodException: No signature of method: ...store()`。 - `aggregate(Scope, 'x')` 的带 Scope 重载也被删除(包括 `aggregate(local, 'x')` 和 `aggregate(global, 'x')`)。 * **典型旧写法**: ```groovy @@ -83,8 +88,11 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 // 新写法:统一使用 discard() g.V().hasLabel('person').discard() - // 在 choose() 或分支中丢弃未匹配元素: - g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) + // 在 choose() 或分支中丢弃未匹配元素与属性缺失元素: + g.V().choose(__.values('age')) + .option(gt(30), __.values('name')) + .option(Pick.none, __.discard()) + .option(Pick.unproductive, __.discard()) ``` --- @@ -122,7 +130,7 @@ HugeGraph 1.8.0 将底层图遍历与查询框架从 Apache TinkerPop 3.5.1 升 - 如需在多个条件同时命中时全部执行,请使用 `union()` 配合 `filter()`。 - 如需在无匹配或属性缺失时将元素过滤抛弃,需显式声明 `Pick.none` 与 `Pick.unproductive` 分支: ```groovy - // 显式丢弃无匹配与属性缺失项 + // 显式丢弃无匹配项以及缺少 age 属性的项 g.V().choose(__.values('age')) .option(gt(30), __.values('name')) .option(Pick.none, __.discard()) @@ -169,14 +177,18 @@ TinkerPop 3.8 引入了原生日期操作函数与步骤,这些能力在 3.5.1 |---|---|---|---| | `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder`
`ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 推荐,默认高效二进制协议 | | `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry, org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry]` | 保持无类型 GraphSON V1 | -| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 无类型 GraphSON V2 | -| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 标准 Typed GraphSON V3 | +| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 标准 Typed GraphSON V2 | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 标准 Typed GraphSON V3 | +| *(1.8 新增)* | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 无类型 GraphSON V2 (`types=false`) | +| *(1.8 新增)* | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | 无类型 GraphSON V3 (`types=false`) | {.td-table--wide} ### 2. HugeGraph Client 1.5.0 能否平滑使用? -* **结论**:**可以继续使用**。 -* 服务端在 1.8.0 中增加了向前兼容层(图别名自动映射与旧认证路径重定向),使用 `hugegraph-client:1.5.0` 进行常规 CRUD、Schema 操作及 REST 请求均可正常连通。 -* **特别注意**:虽然 Client 1.5.0 能建立连接,但客户端所发送的 **Gremlin 脚本内容依然在服务端的 3.8.1 引擎中执行**。因此,客户端代码中拼接的 Gremlin 脚本必须按照上述规则适配。 +* **结论**:**基础 CRUD、Schema 与 Gremlin 查询可以继续使用**。 +* 服务端在 1.8.0 中增加了向前兼容层(图别名自动映射等),使用 `hugegraph-client:1.5.0` 进行常规 CRUD、Schema 操作及 Gremlin 脚本请求均可正常连通。 +* **限制说明**: + - **Auth 鉴权路径**:1.8.0 将用户与鉴权体系重构至 GraphSpace 维度(`graphspaces/{graphspace}/auth/users`),Client 1.5.0 的 `graphs/{graph}/auth/...` 路径并不包含在此重定向范围内,鉴权管理操作需升级 Client。 + - **Gremlin 脚本语法**:客户端所发送的 Gremlin 脚本字符串均在服务端的 3.8.1 引擎中执行,必须按上述规则适配 3.8 语法。 --- @@ -185,18 +197,18 @@ TinkerPop 3.8 引入了原生日期操作函数与步骤,这些能力在 3.5.1 除上述高频变化外,TinkerPop 3.5.1 → 3.8.1 还包含若干深层优化与边缘语义调整。如遇特定场景异常,请查阅下表对应项: ### 附录 1:写入与 Upsert(`mergeV` / `mergeE`) -`mergeV()` 与 `mergeE()` 是 TinkerPop 3.8(3.5.1 中不存在)推荐的标准图数据 Upsert 操作: +在 HugeGraph 1.8.0(自 TinkerPop 3.6.0 起引入)中可使用标准的 `mergeV()` 与 `mergeE()` 执行图数据 Upsert 操作: - **M01**: `onCreate` 的属性 Map 严格继承主匹配 Map,不允许用冲突值覆盖主匹配条件(如匹配条件是 `name: 'A'`,`onCreate` 不能设 `name: 'B'`)。 - **M02**: `mergeE` 不再隐式拿上游顶点填补端点,必须在 Map 中指明 `(Direction.OUT)` 与 `(Direction.IN)`,或使用 `option(Merge.outV, ...)` 显式绑定。 -- **M03**: `onMatch` 与 `onCreate` 的属性冲突在构造期就会被严格校验,而非等到运行时才报错。 +- **M03**: 静态 `onCreate` Map 与 match 检索匹配条件发生键值冲突时,在构造阶段就会被严格校验,而非等到运行时才报错。 - **M04**: `onMatch` 子遍历在 3.8 中接收的是当前已匹配到的 Element 对象,而非最开始输入的 Map。若需引用外部输入参数,请在 merge 前通过 `.as('input')` 保存引用,内部通过 `select('input')` 取值。 ### 附录 2:遍历内部高级步骤与集合行为 - **B07 (`local()` 拆 bulk)**:带 bulk 计数的 Traverser 经过 `local()` 子遍历时会被展开为单个对象处理。若需统计频次,建议使用 `groupCount()`。 - **B09 (`range(local)` 集合解包)**:对列表截取单元素(如 `limit(local, 1)`),新版始终返回 Collection 包装(如 `[1]`),若业务必须获取标量,请在后续追加 `.unfold()`。 - **B11 (`sum()` 返回类型)**:整数流的 `sum()` 结果可能直接返回 Integer 而不是 Long(若无溢出),建议 Java 端统一使用 `Number` 接收。 -- **B14 (`split()` 步骤)**:TinkerPop 3.8 新增步骤。空字符串分隔符在 3.8 中将拆分为单字符列表(如 `'abc'` 拆分为 `['a','b','c']`)。 -- **B15 (`asString()` 步骤)**:TinkerPop 3.8 新增步骤。`asString()` 接收到 null 时会抛出 `IllegalArgumentException`,如需兼容 null 请配合 `choose()` 显式处理。 +- **B14 (`split()` 步骤)**:HugeGraph 1.8 新增步骤。空字符串分隔符将拆分为单字符列表(如 `'abc'` 拆分为 `['a','b','c']`)。 +- **B15 (`asString()` 步骤)**:HugeGraph 1.8 新增步骤。`asString()` 接收到 null 时会抛出 `IllegalArgumentException`,如需兼容 null 请配合 `choose()` 显式处理。 ### 附录 3:多语言客户端差异(GLV) - **Python**:步骤名避免与 Python 关键字冲突,全面使用下划线后缀(如 `filter_()`、`id_()`、`range_()`、`max_()` 等),推荐使用 snake_case(如 `has_label`)。 diff --git a/content/cn/docs/language/hugegraph-gremlin.md b/content/cn/docs/language/hugegraph-gremlin.md index 18e117afc0..3f61c258c7 100644 --- a/content/cn/docs/language/hugegraph-gremlin.md +++ b/content/cn/docs/language/hugegraph-gremlin.md @@ -12,7 +12,7 @@ Gremlin可用于创建图的实体(Vertex和Edge)、修改实体内部属性 > [!NOTE] > **版本与升级提示**:HugeGraph 1.8.0 已将底层 TinkerPop 引擎升级至 **3.8.1**(同时要求 Java 17 与 Groovy 4.0.25)。 -> 部分旧版语法(如 `store()`、`has(key, traversal)`、带 Scope 的 `aggregate()`)已被废弃或语义调整。详见 [1.8 Gremlin 与 TinkerPop 迁移指南](../guides/gremlin-migration-3.8)。 +> 部分旧版语法(如 `store()`、带 Scope 的 `aggregate()` 以及 `has(key, traversal)`)已彻底移除,在 1.8 中调用会直接报错。详见 [1.8 Gremlin 与 TinkerPop 迁移指南](../guides/gremlin-migration-3.8)。 ### TinkerPop Features diff --git a/content/en/docs/changelog/hugegraph-1.7.0-release-notes.md b/content/en/docs/changelog/hugegraph-1.7.0-release-notes.md index d86da02d87..1fc8674740 100644 --- a/content/en/docs/changelog/hugegraph-1.7.0-release-notes.md +++ b/content/en/docs/changelog/hugegraph-1.7.0-release-notes.md @@ -1,7 +1,7 @@ --- title: "HugeGraph 1.7.0 Release Notes" linkTitle: "Release-1.7.0" -weight: 1 +weight: 2 --- > WIP: This doc is under construction, please wait for the final version (BETA) diff --git a/content/en/docs/guides/gremlin-migration-3.8.md b/content/en/docs/guides/gremlin-migration-3.8.md index 80f3239ac6..7ea6c9a02c 100644 --- a/content/en/docs/guides/gremlin-migration-3.8.md +++ b/content/en/docs/guides/gremlin-migration-3.8.md @@ -17,16 +17,21 @@ While bringing substantial performance optimizations and specification alignment ## Top 5 High-Frequency Syntax and Behavioral Changes -Among existing query scripts, the following 5 changes are the most common. **Failure to update these may cause query errors or silently return empty results.** +Among existing query scripts, the following 5 changes are the most common. **Failure to update these will cause query execution errors on HugeGraph 1.8.** -### 1. `has(key, traversal)` Overload Removed (High Risk: Silent Empty Results) +### 1. `has(key, traversal)` Overload Removed (High Risk: Execution Error) * **Impact**: In TinkerPop 3.8.0, the `has(String, Traversal)` and `has(T, Traversal)` overloads were removed. - In the Groovy script engine, legacy code will not throw a compilation error; instead, it **silently falls back to `has(String, Object)`**, comparing the anonymous traversal object itself against vertex/edge properties. In practice, this **silently yields 0 results / empty sets**! + In the Groovy script engine, legacy syntax falls back to `has(String, Object)`. On HugeGraph 1.8, because the graph engine pushes `has()` predicates down into backend queries and validates values with `TraversalUtil.validPropertyValue()`, **it fails immediately with type mismatch errors**: + - Property filter `g.V().has('age', __.is(gt(30)))` throws: + `IllegalArgumentException: Invalid data type of query value '[IsStep(gt(30))]', expect INT for 'age', actual got class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal` + - Label filter `g.V().has(T.label, __.is('person'))` throws: + `HugeException: The label type must be number or string, but got 'class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal'` + *(Note: Pure in-memory TinkerGraph silently returns an empty array `[]`, whereas HugeGraph 1.8 fails strictly).* * **Legacy Query**: ```groovy - // Broken in 3.8: will not throw an error, but silently returns 0 results + // Broken on HugeGraph 1.8: throws Invalid data type exception g.V().has('age', __.is(gt(30))) g.V().has(T.label, __.is('person')) ``` @@ -46,7 +51,7 @@ Among existing query scripts, the following 5 changes are the most common. **Fai ### 2. `store()` Removed & `aggregate()` Scope Overload Removed * **Impact**: - - The `store('x')` step, previously used for lazy side-effect collection, has been completely removed (`No signature of method: store()`). + - The `store('x')` step, previously used for lazy side-effect collection, has been completely removed (`MissingMethodException: No signature of method: ...store()`). - The `aggregate(Scope, 'x')` overload with an explicit `Scope` (both `local` and `global`) has also been removed. * **Legacy Query**: ```groovy @@ -71,21 +76,23 @@ Among existing query scripts, the following 5 changes are the most common. **Fai ### 3. Step `none()` Renamed to `discard()` * **Impact**: - In TinkerPop 3.5.1, `none()` was a traversal step used to discard all incoming traversers (e.g., `g.V().hasLabel('person').none()`, which returned `[]`). - In 3.8.1, this step has been renamed to **`discard()`**. - Meanwhile, 3.8 introduces a new collection predicate step `none(P)` (checking if no elements in a collection match predicate P). Invoking parameterless - `none()` in 3.8.1 fails immediately with: + In TinkerPop 3.5.1, only the traversal step `g.V().none()` existed (which returned an empty result); anonymous `__.none()` was not supported. + In 3.8.0, parameterless `none()` was completely renamed to **`discard()`**, while `none(P)` was repurposed as a collection predicate step. + Calling parameterless `none()` in 3.8.1 (such as `g.V().hasLabel('person').none()`) throws: `IllegalArgumentException: Input predicate to none step can't be null.` * **Recommended Rewrite**: ```groovy - // Legacy (runs on 3.5.1, returning []): + // Legacy (dropped results on 3.5.1, throws predicate can't be null on 3.8.1) g.V().hasLabel('person').none() - // Rewritten for 3.8: use discard() to discard traversers + // Rewritten: use discard() g.V().hasLabel('person').discard() - // Discarding unhandled inputs in choose() branches: - g.V().choose(__.values('age')).option(gt(30), __.values('name')).option(Pick.none, __.discard()) + // In choose() or branches, discard unhandled and missing-property inputs: + g.V().choose(__.values('age')) + .option(gt(30), __.values('name')) + .option(Pick.none, __.discard()) + .option(Pick.unproductive, __.discard()) ``` --- @@ -173,32 +180,36 @@ to `gremlin-util` (`org.apache.tinkerpop.gremlin.util.ser.*`). |---|---|---|---| | `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder`
`ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Recommended default binary serializer | | `GraphSONMessageSerializerV1d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV1` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry, org.apache.hugegraph.io.HugeGraphSONV1MessageIoRegistry]` | Untyped GraphSON V1 | -| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V2 | -| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V3 | +| `GraphSONMessageSerializerV2d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Standard Typed GraphSON V2 | +| `GraphSONMessageSerializerV3d0` | `org.apache.tinkerpop.gremlin.util.ser.GraphSONMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Standard Typed GraphSON V3 | +| *(New in 1.8)* | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV2` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V2 (`types=false`) | +| *(New in 1.8)* | `org.apache.tinkerpop.gremlin.util.ser.GraphSONUntypedMessageSerializerV3` | `ioRegistries: [org.apache.hugegraph.io.HugeGraphIoRegistry]` | Untyped GraphSON V3 (`types=false`) | {.td-table--wide} ### 2. Can HugeGraph Client 1.5.0 Continue to Work? -* **Verdict**: **Yes**. -* HugeGraph Server 1.8.0 provides backward-compatible adapters (graph alias mapping and legacy auth path redirection). Applications using `hugegraph-client:1.5.0` can continue standard CRUD, schema management, and REST operations without forced SDK upgrades. -* **Important Note**: Although Client 1.5.0 connects successfully, **all submitted Gremlin script strings are executed on the 3.8.1 server engine**. Therefore, Gremlin queries constructed in your code must comply with the 3.8 rules described above. +* **Verdict**: **Basic CRUD, schema operations, and Gremlin queries continue to work**. +* HugeGraph Server 1.8.0 provides backward-compatible adapters (such as default graphspace alias mapping), allowing `hugegraph-client:1.5.0` to connect for standard data operations, schema management, and Gremlin query scripts. +* **Limitations**: + - **Auth Paths**: Server 1.8.0 migrates authentication to GraphSpace scopes (`graphspaces/{graphspace}/auth/users`). The legacy Client 1.5.0 path `graphs/{graph}/auth/...` is not redirected to this new endpoint, so auth operations require upgrading the client. + - **Gremlin Query Strings**: All Gremlin query strings submitted by the client are evaluated on the server's 3.8.1 engine and must adhere to 3.8 syntax. --- ## Full Compatibility Reference ### Appendix 1: Writes & Upsert (`mergeV` / `mergeE`) -`mergeV()` and `mergeE()` are new steps in TinkerPop 3.8 (absent in 3.5.1) for graph upserts: +HugeGraph 1.8.0 (introduced upstream in TinkerPop 3.6.0) supports standard `mergeV()` and `mergeE()` steps for graph upserts: - **M01**: `onCreate` property maps strictly inherit the search match map. Conflicting keys cannot overwrite matched properties. - **M02**: `mergeE` no longer implicitly binds incoming/outgoing vertices from upstream traversers; specify `Direction.OUT` and `Direction.IN` in the map or use explicit options. -- **M03**: Conflicting `onCreate` / `onMatch` maps are validated during construction rather than deferred to runtime execution. +- **M03**: Construction-time validation applies when a static `onCreate` map attempts to override keys defined in the search-criteria match map. - **M04**: Child traversers in `onMatch` receive the matched Element object rather than the original input Map. Preserve input map references prior to merge with `.as('input')` and reference with `select('input')`. ### Appendix 2: Advanced Traversal Steps & Collections - **B07 (`local()` unpacks bulk)**: Traversers with bulk counters are expanded into individual items when entering `local()` child traversals. Use `groupCount()` for frequency analysis. - **B09 (`range(local)` collection unpacking)**: Slicing a single item from a list (e.g., `limit(local, 1)`) consistently returns a Collection wrapper (`[item]`). Append `.unfold()` if a scalar is needed. - **B11 (`sum()` return type)**: Summing integer streams without overflow may return `Integer` instead of `Long`. Clients should accept `Number`. -- **B14 (`split()` step)**: New step in TinkerPop 3.8. An empty string separator splits the string into individual characters. -- **B15 (`asString()` step)**: New step in TinkerPop 3.8. Throws `IllegalArgumentException` on null inputs. +- **B14 (`split()` step)**: HugeGraph 1.8 new step. An empty string separator splits the string into individual characters. +- **B15 (`asString()` step)**: HugeGraph 1.8 new step. Throws `IllegalArgumentException` on null inputs. ### Appendix 3: GLV Client Variations - **Python**: Avoids Python keyword conflicts by appending an underscore to step names (`filter_()`, `id_()`, `range_()`, `max_()`). diff --git a/content/en/docs/language/hugegraph-gremlin.md b/content/en/docs/language/hugegraph-gremlin.md index 8b9675dede..e33d16edf3 100644 --- a/content/en/docs/language/hugegraph-gremlin.md +++ b/content/en/docs/language/hugegraph-gremlin.md @@ -12,7 +12,7 @@ Gremlin can be used to create entities (Vertex and Edge) of a graph, modify the > [!NOTE] > **Version & Migration Note**: HugeGraph 1.8.0 upgrades its underlying TinkerPop engine to **3.8.1** (along with Java 17 and Groovy 4.0.25). -> Certain legacy syntax patterns (e.g., `store()`, `has(key, traversal)`, and scoped `aggregate()`) have been deprecated or modified. See the [1.8 Gremlin & TinkerPop Migration Guide](../guides/gremlin-migration-3.8) for details. +> Legacy syntax patterns such as `store()`, scoped `aggregate()`, and `has(key, traversal)` have been completely removed and now fail on 1.8. See the [1.8 Gremlin & TinkerPop Migration Guide](../guides/gremlin-migration-3.8) for details. ### TinkerPop Features From 5b3a52bb791e9584f56101d61d8b8f6b5f9c8829 Mon Sep 17 00:00:00 2001 From: contrueCT Date: Fri, 23 Oct 2026 16:17:04 +0800 Subject: [PATCH 4/4] docs: register 1.8 Gremlin guide and release notes in version routes Register the bilingual 1.8 Gremlin migration guide and 1.8.0 release notes pages in data/version_routes.json for canonical and version-switch lookup. Co-Authored-By: Claude Code --- data/version_routes.json | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/data/version_routes.json b/data/version_routes.json index 46ae1f6fa0..0fa8182ca6 100644 --- a/data/version_routes.json +++ b/data/version_routes.json @@ -141,6 +141,13 @@ "1.3": null, "1.0": null }, + "cn:changelog/hugegraph-1.8.0-release-notes": { + "latest": "cn/docs/changelog/hugegraph-1.8.0-release-notes/", + "1.7": null, + "1.5": null, + "1.3": null, + "1.0": null + }, "cn:cla": { "latest": "cn/docs/cla/", "1.7": "cn/docs/cla/", @@ -463,6 +470,13 @@ "1.3": "cn/docs/guides/faq/", "1.0": "cn/docs/guides/faq/" }, + "cn:guides/gremlin-migration-3.8": { + "latest": "cn/docs/guides/gremlin-migration-3.8/", + "1.7": null, + "1.5": null, + "1.3": null, + "1.0": null + }, "cn:guides/hugegraph-docker-cluster": { "latest": "cn/docs/guides/hugegraph-docker-cluster/", "1.7": null, @@ -883,6 +897,13 @@ "1.3": null, "1.0": null }, + "en:changelog/hugegraph-1.8.0-release-notes": { + "latest": "docs/changelog/hugegraph-1.8.0-release-notes/", + "1.7": null, + "1.5": null, + "1.3": null, + "1.0": null + }, "en:cla": { "latest": "docs/cla/", "1.7": "docs/cla/", @@ -1205,6 +1226,13 @@ "1.3": "docs/guides/faq/", "1.0": "docs/guides/faq/" }, + "en:guides/gremlin-migration-3.8": { + "latest": "docs/guides/gremlin-migration-3.8/", + "1.7": null, + "1.5": null, + "1.3": null, + "1.0": null + }, "en:guides/hugegraph-docker-cluster": { "latest": "docs/guides/hugegraph-docker-cluster/", "1.7": null,