bitflicker64 commented on code in PR #541:
URL: https://github.com/apache/hugegraph-doc/pull/541#discussion_r4322278042


##########
content/en/docs/guides/gremlin-migration-3.8.md:
##########
@@ -0,0 +1,218 @@
+---
+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 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.**
+
+### 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**!

Review Comment:
   Important: On HugeGraph 1.8 this query does not return an empty result; it 
fails. HugeGraph pushes `has()` into its own query, and 
`TraversalUtil.validPropertyValue()` rejects a traversal as the value. I ran 
the guide's two legacy lines on an in-process 1.8.0 build (TinkerPop 3.8.1, 
memory backend, `age` as an INT key with a range index). `g.V().has('age', 
__.is(gt(30)))` fails with `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'))` fails with `HugeException: The label 
type must be number or string, but got 'class 
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal'`.
 The same error appears when the `has()` sits inside `where()` or `filter()`, 
or follows `in()`. The silent `[]` happens on TinkerGraph, not on HugeGraph. 
Users who follow this text will look for queries tha
 t return nothing, while their logs show an error that the guide never 
mentions. Please describe the 1.8 symptom as this error and quote its text, and 
keep the TinkerGraph silent case as a side note at most. Line 29 of this page 
and line 17 of both release notes make the same claim. The CN guide needs the 
same change at lines 22, 26 and 29.



##########
content/en/docs/guides/gremlin-migration-3.8.md:
##########
@@ -0,0 +1,218 @@
+---
+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 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.**
+
+### 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**:
+  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 (runs on 3.5.1, returning []):
+  g.V().hasLabel('person').none()
+
+  // 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())

Review Comment:
   Minor: On a vertex without `age`, this example does not discard the input. 
`Pick.none` only covers values that match no option; when the choice traversal 
returns nothing, 3.8.1 passes the element through. On TinkerGraph 3.8.1 this 
exact line returns `[v[3], josh, v[5], peter]`. On the HugeGraph 1.8.0 build, a 
`person` vertex without `age` comes back as `v[1:noage]`. Section 5 already 
adds `.option(Pick.unproductive, __.discard())` for this case. Please add it 
here as well, or change the comment so it says only unmatched values are 
dropped. CN lines 86-87 need the same change.



##########
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.

Review Comment:
   Minor: `store()` and `aggregate(Scope, ...)` are removed, not deprecated. On 
3.8.1, `g.V().store('x')` fails with `MissingMethodException: No signature of 
method: ...DefaultGraphTraversal.store()`, and `aggregate(local, 'x')` fails 
the same way. On HugeGraph 1.8, `has(key, traversal)` fails with `Invalid data 
type of query value`. "Deprecated" suggests old scripts still run with a 
warning. Please say these forms were removed and now fail. CN line 15 (已被废弃) 
needs the same change.



##########
content/en/docs/guides/gremlin-migration-3.8.md:
##########
@@ -0,0 +1,218 @@
+---
+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 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.**
+
+### 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**:
+  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 (runs on 3.5.1, returning []):
+  g.V().hasLabel('person').none()
+
+  // 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())
+  ```
+
+---
+
+### 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**:
+  - **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:
+  ```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())
+  ```
+
+---
+
+## New Steps & Functions in 1.8 (TinkerPop 3.8)
+
+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
+  // 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)
+  ```
+
+---
+
+## Server Configuration and Client Compatibility
+
+### 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 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`<br>`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 |

Review Comment:
   Important: These two rows map typed serializers to untyped ones. In 
TinkerPop 3.5.1, `GraphSONMessageSerializerV2d0` serves 
`application/vnd.gremlin-v2.0+json` and `GraphSONMessageSerializerV3d0` serves 
`application/vnd.gremlin-v3.0+json`, and both are typed. Their 3.8.1 names are 
`GraphSONMessageSerializerV2` and `GraphSONMessageSerializerV3`, which serve 
the same MIME types. `GraphSONUntypedMessageSerializerV2` and 
`GraphSONUntypedMessageSerializerV3` serve 
`application/vnd.gremlin-v2.0+json;types=false` and 
`application/vnd.gremlin-v3.0+json;types=false` instead. I printed these lists 
from `mimeTypesSupported()` in gremlin-driver 3.5.1 and gremlin-util 3.8.1. If 
a user edits a 1.7.0 yaml row by row with this table, a client that asks for 
typed GraphSON v2 or v3 finds no matching serializer, and its requests fail. 
The `gremlin-server.yaml` on master has both forms: untyped V1/V2/V3, then 
typed `GraphSONMessageSerializerV2` and `GraphSONMessageSerializerV3`, the 
order `docs/serve
 r-runtime.md` describes. Please map `V2d0` to `GraphSONMessageSerializerV2` 
and `V3d0` to `GraphSONMessageSerializerV3`, and list the untyped V2/V3 entries 
as additions that the 1.8.0 file brings. The CN table (lines 172-173) needs the 
same change. Its V3 row also labels the untyped class "标准 Typed GraphSON V3".



##########
content/en/docs/changelog/hugegraph-1.8.0-release-notes.md:
##########
@@ -0,0 +1,43 @@
+---
+title: "HugeGraph 1.8.0 Release Notes"
+linkTitle: "Release-1.8.0"
+weight: 1

Review Comment:
   Minor: The 1.7.0 release notes also use `weight: 1`. The changelog pages 
step by 2 (1.5.0 is 3, 1.3.0 is 5) so the newest release comes first. When 
weights are equal, Hugo orders pages by date and then by link title. These 
pages have no `date`, so `Release-1.7.0` sorts above `Release-1.8.0` in the 
sidebar. `weight: 0` does not work either, because Hugo treats 0 as unweighted 
and puts the page last. Please give 1.7.0 a larger weight (for example 2) in 
both languages, or use a negative weight here. The CN page has the same front 
matter.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to