Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/cn/docs/changelog/hugegraph-1.7.0-release-notes.md
Original file line number Diff line number Diff line change
@@ -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)
Expand Down
42 changes: 42 additions & 0 deletions content/cn/docs/changelog/hugegraph-1.8.0-release-notes.md
Original file line number Diff line number Diff line change
@@ -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()`)。

> 完整改写代码对照与全量细则速查表请参阅:[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 分词器**:因开源协议合规,默认发行包不再捆绑 GPLv3 的 `word-1.3.jar`。配置了 `search.text_analyzer=word` 的图仍受支持,
只需将 `word-1.3.jar` 放入 Server 的 `lib/` 目录即可正常使用;亦可切换为内置的 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
- 支持 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
227 changes: 227 additions & 0 deletions content/cn/docs/guides/gremlin-migration-3.8.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
---
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 闭包等大多数逻辑仍可正常运行。

---

## 核心重点:最常用的 5 大语法与行为变化

在已有的业务查询中,以下 5 项改动最为高频,**若不改写在 HugeGraph 1.8 中会直接导致执行报错**,请优先重点排查。

### 1. `has(key, traversal)` 重载删除(高危:查询执行报错)

* **影响说明**:
在 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
// 错误!在 HugeGraph 1.8 下执行将抛出 Invalid data type 异常
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')` 步骤已被完全删除,在 3.8.1 中直接报错 `MissingMethodException: 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()`

* **影响说明**:
在 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
// 旧写法(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())
.option(Pick.unproductive, __.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()` 语义收敛

* **影响说明**:
- **缺失属性处理**:当选择子遍历依赖的属性缺失时,TinkerPop 3.5.1 会直接抛出异常:
`IllegalArgumentException: The provided traverser does not map to a value: v[3]->[PropertiesStep([age],value)]`。
在 3.8.1 中,缺少对应属性的元素不再报错,而是默认原样放行穿透。
- **单分支执行**:当多个 `option()` 条件同时命中时,旧版可能会把多个匹配分支全部执行;新版**只执行第一个命中的分支**。
- **默认放行机制**:如果没有任何一个 `option()` 匹配,新版**默认将输入元素原样向下游放行**(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())
.option(Pick.unproductive, __.discard())
```

---

## 1.8 新增步骤与内置函数(TinkerPop 3.8)

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
// 获取当前时间 OffsetDateTime
g.inject(datetime())

// 计算日期毫秒差并转换为秒
g.inject(datetime('2026-10-19T00:00:00Z')).dateDiff(datetime('2026-10-18T00:00:00Z'))
.math('_ / 1000').asNumber(GType.LONG)
```

---

## 服务端配置与客户端连接兼容

### 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.*`) | 所需 Builder / Registry | 说明 |
|---|---|---|---|
| `GraphBinaryMessageSerializerV1` | `org.apache.tinkerpop.gremlin.util.ser.GraphBinaryMessageSerializerV1` | `builder: org.apache.hugegraph.io.HugeGraphTypeSerializerRegistryBuilder`<br>`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.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 能否平滑使用?
* **结论**:**基础 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 语法。

---

## 全量细则速查表

除上述高频变化外,TinkerPop 3.5.1 → 3.8.1 还包含若干深层优化与边缘语义调整。如遇特定场景异常,请查阅下表对应项:

### 附录 1:写入与 Upsert(`mergeV` / `mergeE`)
在 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**: 静态 `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()` 步骤)**: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`)。
- **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 适配与能力边界
- **元属性保持不支持(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()`) 提供完整支持。
2 changes: 1 addition & 1 deletion content/cn/docs/introduction/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -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(Cassandra、MySQL、PostgreSQL 等历史后端已在 1.7.0 禁用并在 1.8.0 彻底移除)

主要模块包括 `hugegraph-core`、存储后端模块和 `hugegraph-api`。Core 实现图模型、事务和查询逻辑,后端模块负责连接具体存储系统,API 模块负责 HTTP 接入。当前 REST 资源路径包含图空间与图名称,例如:

Expand Down
Loading
Loading