You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
docs: add Cypher language guide, compatibility matrix, and Neo4j migration guide (EN/CN) - #499
Three pages, each with full EN + CN mirrors under content/{en,cn}/docs/language/:
hugegraph-cypher.md — how to use Cypher in HugeGraph: the /cypher REST endpoint, Java client (CypherManager), MATCH/WHERE/RETURN, CREATE/SET/DELETE, aggregation, Gremlin equivalents for unsupported constructs, and an honest Known limitations section (no parameterized queries in released versions — a missing $param evaluates to null —, no CALL procedures, single statement per request).
cypher-compatibility.md — a verification record of the parameter-binding change: request forms, verified behavior per test, the baseline failure and its fix, and the unverified areas.
migrate-from-neo4j.md — what carries over directly, habits that change (strong schema, schema DDL via REST APIs instead of Cypher), and a suggested migration path.
All three new pages are registered in data/docs_nav.json (group tree, section tree, breadcrumb, section children) and data/version_routes.json (latest only — the pages do not exist in 1.0–1.7).
The compatibility page records unverified areas explicitly; running the openCypher TCK against a live server is the natural follow-up.
ASF code PR #3289 was merged into master on 2026-10-08; its organization mirror #238 is closed. The bilingual pages now distinguish merged master support (the 1.8.0 development line) from the latest published 1.7.0 release, retain the verified request/binding boundaries, and explain that the translator's historical TCK percentage is not a HugeGraph end-to-end compatibility rate. The code dependency is merged, so this documentation PR can be reviewed and merged independently.
Conceptual overview
Conceptual documentation overview of Cypher translation, version boundaries and staged Neo4j data migration. This diagram does not establish migration or release acceptance.
- Document the Cypher API (REST endpoint, Java client), MATCH/WHERE/RETURN,
CREATE/SET/DELETE, aggregation, and Gremlin equivalents for unsupported
constructs
- State known limitations honestly: no parameterized queries, partial clause
coverage via the cypher-for-gremlin transpiler, no CALL procedures,
single statement per request
- Update language section indexes (EN/CN) to cover both languages
- Register the page in data/docs_nav.json (group tree, section tree,
active_path breadcrumb, section children) and data/version_routes.json
(latest only; page does not exist in 1.0-1.7)
- Closes apache/hugegraph-doc cypher doc gap tracked in apache/hugegraph#2205
- cypher-compatibility.md: feature matrix with explicit evidence tiers
(documented examples / transpiler TCK self-report / API surface /
untested), failure behaviour, and Gremlin workarounds
- migrate-from-neo4j.md: what carries over, habits to change (strong
schema, no Cypher DDL/params/CALL), suggested migration path
- Register both pages in data/docs_nav.json and data/version_routes.json
(latest only; pages do not exist in 1.0-1.7)
- CN anchors verified against Hugo-slugified heading ids
- Companion pages to the Cypher language guide; related to #2205
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The compatibility matrix and Known limitations list mark MERGE ON CREATE/ON MATCH SET, =~, NOT ... IN and EXPLAIN as not supported, but HugeGraph's transpiler setup handles them. The migration page also has a broken Loader link, and the $param behaviour is described as a failure when the query actually returns no rows. Evidence: I checked the pages against apache/hugegraph master dbb6663a8 (CypherAPI, CypherClient, CypherOpProcessor, conf/gremlin-server.yaml) and hugegraph-toolchain CypherManager/HugeClient.cypher(). I translated 25 statements from the pages with translation-1.0.4.jar and the server's default translator definition. I resolved every internal link against the PR head. The REST endpoints, auth header requirement, Java client call, single-statement rule, CALL failure, DDL failure, date()/datetime() and map projection rows match the source. The EN and CN pages match each other. The only latest-head workflow run, "Build and deploy site", is waiting for maintainer approval (action_required).
Thanks for the detailed translator-level review. I’ve started validating core Cypher reads and writes against TinkerPop 3.8 on Java 17, and am investigating a minimal parameter wrapper while keeping translation-1.0.4. I’ll update this PR with the verified EN/CN documentation changes once the runtime results are available.
The implementation is now available in draft hugegraph/hugegraph#238,
at c3b2f3e3b9ff1de0495260d6eec0b16816d7f095, based on the Java 17 / TinkerPop 3.8.1 branch.
It retains translation:1.0.4 and adds bound JSON requests, parameter validation, and execution-thread rollback.
On the pinned baseline 27a7c9b, failed writes left partial data that became visible after later reads in two
reproductions. The proposed fix passes the regression, including native readback and 32 subsequent query/readback
checks. On Java 17.0.20.1 + TinkerPop 3.8.1 + RocksDB, all 20 Cypher API tests and 11 focused unit tests now pass.
Related Gremlin/Login regression, formatting and compilation also pass (one inapplicable Gremlin backend test skips).
This existing documentation PR has been updated with a test-mapped matrix and links to the fixed source revision.
The results describe this development change; advanced constructs and other backends remain unverified.
- Record the nine-request legacy CRUD sample and tested runtime.
- Describe delayed failed-write residue and the failed atomicity check.
- Link the evidence and limit claims to the observed scope.
Final documentation preview evidence (before/after screenshots use the same viewport).
The final strict scripts/hugo.sh build exited 0 with Go 1.27.0 and Hugo 0.165.0 Extended (darwin-arm64); output: EN 292 pages, CN 290 pages. The compatibility matrix maps 31 passing focused tests (Cypher API 20/20, client 7/7, processor 4/4) to code PR #238 at source commit c3b2f3e3.
- Link measured Java 17, TinkerPop 3.8.1, and RocksDB results to code PR apache#238.
- Document parameter requests and the failed-write regression.
- Limit compatibility claims to tested cases; mark advanced features unverified.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The migration guide overstates when Gremlin is a fallback and carries an outdated draft status for the linked source PR. Evidence: the page's migration table directs schema DDL and procedures to REST APIs; gh -R hugegraph/hugegraph pr view 238 reports the linked PR as open and not draft.
- guide: MERGE ON CREATE/ON MATCH, =~ and NOT ... IN translate but are
unverified end-to-end; only map projections and datetime() fail translation
- guide: $param statement runs with null binding (empty result), not an error;
JSON-bound parameters land via hugegraph/hugegraph#238
- guide: add EXPLAIN tip (translated Gremlin in result.data[0].translation),
PROFILE unsupported
- migration: point Loader links at /docs/quickstart/toolchain/hugegraph-loader/,
drop undefined 'bulkport'; scope the Gremlin-fallback claim to query
constructs (DDL and CALL go through REST APIs)
- migration: qualify parameter binding by version in habits table and limits
- compatibility: drop 'draft' label from PR apache#238 (now open)
- version_routes.json: insert the 6 new page entries in sorted locale order
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The aggregation example groups two separate Cypher statements in one request, contrary to the documented single-statement limit. Evidence: the changed code fence contains two MATCH/RETURN statements; the limitations section permits one statement per request.
Reply to @imbajin (2026-09-26, code-fence comment)
@imbajin Thanks for catching this — fixed in 3599a2b. Every example fence in hugegraph-cypher.md now contains exactly one statement, in both EN and CN:
the aggregation fence you flagged → split into two labeled fences (content/en/docs/language/hugegraph-cypher.md:111 and :116; CN mirror at the same lines);
the Read / Create / Delete fences had the same shape (multiple statements grouped in one block), so they were split the same way for consistency with the "single statement per request" rule.
No wording changes elsewhere in the page.
Reply to the 2026-09-26 review threads
1. EXPLAIN tip vs. compatibility record (hugegraph-cypher.md:133, EN + CN) — fixed in 3599a2b.
The tip no longer presents EXPLAIN → result.data[0].translation as a guaranteed response contract. It now says the statement is parsed with the EXPLAIN option and the translated Gremlin is expected in result.data[0].translation — translator-level behavior, not yet verified end-to-end on a server — with a link to the compatibility notes. PROFILE remains unsupported.
2. "apache/hugegraph#238 URL returns 404" (6 threads: cypher-compatibility.md:58, hugegraph-cypher.md:126, migrate-from-neo4j.md:31, plus the CN mirrors) — no change; the cited URL does not exist on this branch.
All #238 links in the three pages point to https://github.com/hugegraph/hugegraph/pull/238 (verified open: "fix(cypher): support bound queries safely"). apache/hugegraph#238 appears nowhere in the changed files, so there is no broken link to fix. If the bot reviewed an intermediate revision where the link was worded differently, the current head supersedes it.
Where we intentionally did NOT change
migrate-from-neo4j.md:45 / CN :43 — the second Loader mention links to the GitHub apache/hugegraph-toolchain/tree/master/hugegraph-loader directory; the link is live (repo active, default branch master), and no review finding targets it. The in-doc Loader link that was flagged earlier (/docs/quickstart/toolchain/hugegraph-loader/) is already in place at line 34/33.
data/*.json — untouched by this round; the 2026-09-25 sort-order fix is already in the tree.
Compatibility/migration page content — the 2026-09-26 threads raise no new factual issue beyond the two items above.
Already-resolved prior wave (context only)
The 16 review threads from 2026-09-24/25 (bitflicker64 ×4: matrix rows for MERGE ... ON CREATE/ON MATCH SET, =~, NOT ... IN, EXPLAIN/PROFILE split, $param null-evaluation caveat, Loader link; Copilot ×10: CN mirrors, PR-description scope, version_routes.json ordering; imbajin ×2: Gremlin-fallback scoping, "draft" label) were all addressed in commit debb318 ("docs: address cypher page review feedback") with per-thread replies posted on 2026-09-25. The PR description was re-scoped to the verification-record format, dropping the per-row evidence-tier promise. This push (3599a2b) only adds the 2026-09-26 fixes above.
Commit / readback
Branch: docs/cypher-language-page-2205 (fast-forward debb31848..3599a2bdf, no force)
This says a Gremlin equivalent always works for anything Cypher cannot express, but the same page documents gaps that fail during translation and CALL features that map to REST APIs rather than a Gremlin query. Please qualify this as applying where a Gremlin equivalent exists, and mention the REST fallback for other unsupported features.
The compatibility page classifies EXPLAIN/PROFILE as not verified, but this sentence makes the stronger claim that PROFILE is unsupported. That can cause users to reject a feature that may work in a different translator/server combination; keep the statement at the documented evidence level.
Link IndexLabel API and clarify unique index mapping
This link lands on the schema overview, which only documents reading the complete schema; the create operation for indexes is documented under the IndexLabel API, and HugeGraph's constraint equivalent is a unique index. Link directly to that API and qualify the constraint mapping so migration users can actually perform this step.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The guide overstates accepted Basic credentials, and the migration page links index creation to a read-only schema overview. The Chinese parameter contract and TCK percentage also need correction. Evidence: CypherAPI decoder/split behavior, the GET-only Schema API page versus POST IndexLabel API, and the 879/958 calculation.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The compatibility page documents request forms and binding rules from an unmerged change on the hugegraph/hugegraph fork as verified behaviour, with no release qualifier, and contradicts the guide's released-version $param behaviour. Evidence: apache/hugegraph master CypherAPI (@Consumes(APPLICATION_JSON), raw body only), master CypherApiTest methods, git merge-base --is-ancestor 27a7c9b origin/master (not an ancestor), TinkerPop 3.5.1 in master hugegraph-server/pom.xml versus 3.8.1 in 27a7c9b.
A maintainer review flagged that the request-forms table presents forms from an
unmerged change as verified released behaviour, with no release qualifier, and
that it contradicts the guide's released-version `$param` statement.
- state up front that no row describes a released HugeGraph version: releases
expose only `GET ?cypher=` and `POST application/json` with a raw body
- add an "In a released version" column; mark `text/plain` and the JSON-object
bound-parameter form as introduced by hugegraph/hugegraph#238
- link the tested commit to apache/hugegraph and record that it has diverged
from `master` (10 ahead, 5 behind) while `master` ships TinkerPop 3.5.1
- record that PR apache#238 is open and unmerged against a task branch
- cross-link both locales to the guide's Known limitations section
Thanks for the second pass — both points are correct and the page has been corrected.
What changed
Release qualifier up front. The scope section now states that no row on the page describes a released HugeGraph version, spells out the two request forms a released build exposes (GET ?cypher= and POST application/json with a raw body), and says that released versions take no bound parameters.
Per-row availability. The request-forms table gained an In a released version column. GET ?cypher= and the raw-body POST are marked available; POST text/plain and the JSON-object bound-parameter form are marked No — introduced by #238, with a note that the JSON object form is not available in any release and that on released versions a $param statement runs with the binding bound to null and returns no rows. That now agrees with the guide's Known limitations bullet instead of contradicting it.
Provenance corrected. The tested commit link points at apache/hugegraph@27a7c9b rather than the contributor fork, and the page records that the commit has diverged from master (10 commits ahead, 5 behind) while master declares tinkerpop.version3.5.1 and its CypherAPI is @Consumes(APPLICATION_JSON) with a raw String cypher body. The hugegraph/hugegraph#238 reference now records that the PR is open and unmerged against the task/tp381-3-upgrade-validation branch.
Both the English and Chinese pages carry the same change; statement lines stay byte-identical between locales.
One question so the wording matches your intent: the tested tree is a TinkerPop 3.8 development line, so if master is the only thing readers should be told about, the alternative is to move all of the request-form and binding detail behind an explicit not in any release heading rather than keeping it in the table with a column. Happy to restructure that way if you prefer it.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The request contract, test mapping, links and navigation data check out against apache/hugegraph 5039e5b and a strict build of this head, but the guide's range-predicate example fails on the schema the page names because person.age has no range index, and the released-version note says a write with a missing $param stores null when 1.7.0 removes the property or stores the translator's marker string. Evidence: read the full diff at 4290c2b (11 files) and the earlier review threads; compared CypherAPI, CypherOpProcessor, CypherClient and the three Cypher test classes at 5039e5b with the pages (23/7/8 tests, all 26 cited method names, the fixed 16-binding limit, the null marker); translated the guide examples with translation-1.0.4; ran the guide examples and the missing-parameter cases against a 1.7.0 server loaded with scripts/example.groovy; versioning.py build and validate for latest pass at this head, dist/validate-links.sh passes, internal links and anchors of the six new pages resolve in the built site, and the nine external links return 200. The only workflow run at this head is waiting for maintainer approval, so there is no CI result yet.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The sample CREATE sequence can replace a seeded primary-key vertex; the migration guide also omits required index and ID-field setup. Evidence: HugeGraph 1.7.0 example.groovy seeds the conflicting IDs, and SeaTunnel 3.0.0 requires explicit ID fields and only auto-creates label/property schema.
- Add a RANGE index on person.age to the assumed schema and state that
property predicates need a covering index (mirrored in the habits table
of the migration page and the compatibility notes).
- Use names absent from scripts/example.groovy (alice/bob/carol) in the
create/update/delete examples so PRIMARY_KEY ids do not replace seed vertices.
- Document that a missing $param in a write removes the property on SET and
stores a marker string or fails on CREATE (reviewer-measured on 1.7.0).
- Rewrite the SeaTunnel step: idFields are required for every non-AUTOMATIC
strategy, edges need sourceConfig/targetConfig.idFields, the query must
return the ID column, and mappings do not create IndexLabels.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LHLbjw9SjXQc47Zj7eFuAd
Thanks, all three points are addressed on the new head.
Range predicate without a RANGE index: the schema section now requires a RANGE index on person.age (the page gives the personByAgeindexLabel statement to add to the scripts/example.groovy schema), says that a WHERE property predicate needs a covering index, and migrate-from-neo4j.md has a new row for it. cypher-compatibility.md names the fixture schema used for the 5039e5b run. EN and CN (21083db).
Missing $param on writes: the wording no longer says a write stores null. It now says SET removes the property (or fails on a non-null key) and CREATE stores the " cypher.null" marker string or fails the type check. EN and CN (21083db).
160-character wrap: the five files are rewrapped in 70a1278. The only lines still over 160 characters are single-line links to the test sources, which cannot be split. Wording is unchanged; dist/validate-links.sh passes and a Hugo build of the head succeeds.
Thanks, all three points are addressed in 21083db (EN and CN).
CREATE replacing the seeded peter vertex: the create/match/update/delete examples now use alice, bob and carol, which are not in example.groovy.
CUSTOMIZE_STRING without idFields: the migration page now says the query must return the Neo4j ID, declares it in schema.fields, sets the vertex idFields to it, and maps the edge source and target ID fields.
mappings and IndexLabels: step 2 now says mappings can replace pre-creating PropertyKeys, VertexLabels and EdgeLabels, while the IndexLabels still have to be created separately.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The fixes in 21083db and 70a1278 for the open threads hold at this head: the range example now names its RANGE index, the missing-$param write behaviour matches 1.7.0, the create, update and delete examples avoid the seeded names, the SeaTunnel idFields and IndexLabel notes are in place, and EN and CN agree. One new Minor note: the index rule added in this round says every WHERE property predicate needs an index, which is wrong for primary-key equality lookups and for conditions on adjacent vertices. Evidence: read the full diff e6389aa..70a1278 (11 files) and the delta 4290c2b..70a1278 in a detached worktree. At apache/hugegraph 1.7.0 and master 06f90a9f0 I checked scripts/example.groovy (seeded names, personByCity and personByAgeAndCity SECONDARY only), GraphTransaction.optimizeQuery (label plus all primary keys becomes an id query), IndexLabelBuilder.checkPrimaryKeyIndex and checkRepeatRangeIndex (the suggested personByAge range index is accepted), and HugeVertexStep.queryAdjacentVertices. All 26 cited test methods exist at 5039e5b. A strict scripts/hugo.sh build passes (EN 294 / CN 292), dist/validate-links.sh passes, the CN and EN anchors resolve in the built site, every external link returns 200, and the new prose stays within 160 characters except the three test-source links and the edited one-line _index.md paragraph. scripts/test_versioning passes 80/80. materialize_docs_navigation gives latest pages=95 and treeSha256 fd869e87..., which matches DOCS_NAV_EXPECTED_STATS, both at this head and on a clean merge with master f0107c6. The only workflow run at this head, 'Build and deploy site', is action_required and waiting for maintainer approval.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The migration table maps all Neo4j CREATE CONSTRAINT forms to the IndexLabel API, although HugeGraph stores primary-key and required-property rules on VertexLabels. Evidence: exact-head migration text and the linked IndexLabel and VertexLabel API definitions.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The 2026-10-17 merge leaves the navigation and route data correct, and EN and CN agree, but the guide's authentication paragraph is wrong for master: since apache/hugegraph#3290 and #3366, URL-safe Basic credentials that contain - or _ fail there, and no header is needed when authentication is disabled. Evidence: of the PR's own files, merge 0782770 changes only data/docs_nav.json, data/version_routes.json and scripts/versioning.py. In a detached worktree at 0782770, materialize_docs_navigation for latest gives pages=98, removed=4, treeSha256 8491850c..., which matches DOCS_NAV_EXPECTED_STATS. For 1.7 and 1.5 against the release-1.7.0 and release-1.5.0 content, it also matches (85/11 and 77/19, same tree hashes). scripts/test_versioning.py passes 80/80, dist/validate-links.sh passes, and strict scripts/hugo.sh build passes (EN 323 / CN 321). I read CypherAPI at apache/hugegraph 1.7.0 and master f5d9885, the diffs of #3290 (62faab73d), #3366 (8fe10180d) and #3259 (a0aae8e7e), and master docs/cypher-api.md. I also ran Base64.getDecoder() on a URL-safe credential locally. The only workflow run at this head, 'Build and deploy site' 39038694697, is action_required and waiting for maintainer approval. The open threads on the index rule (hugegraph-cypher.md:60) and CREATE CONSTRAINT (migrate-from-neo4j.md:31) still apply and are not repeated.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: The fixes in 1e5df57 hold for the auth paragraph on master and 1.7.0, the dated compatibility pin, and the primary-key exception to the index rule. The new constraint row in the migration guide still has a gap: it leaves out HugeGraph's UNIQUE IndexLabel and sends key-style constraints to primary_keys, which overwrites a duplicate instead of rejecting it. Two minor wording points remain: the English index sentence no longer limits itself to WHERE property predicates, and "1.7.0 and earlier" does not hold for 1.0.0. Evidence: read the full diff against base 278fdcb (13 files) and the 0935438..1e5df57 delta (8 files). Read CypherAPI at apache/hugegraph 1.0.0, 1.2.0, 1.3.0, 1.5.0, 1.7.0 and master 90790e86 (the anonymous client from #3366, Base64.getDecoder() and split(":", 2) from #3290), GraphTransaction.optimizeQuery (label plus all primary keys becomes an IdQuery), and IndexType.UNIQUE with GraphIndexTransaction.updateIndex ("Unique constraint ... conflict"), which is in every release from 1.0.0 on. At this head, materialize_docs_navigation for latest gives pages=98, removed=4, treeSha256 8491850c..., the same as DOCS_NAV_EXPECTED_STATS. scripts/test_versioning.py passes 85/85 and dist/validate-links.sh passes. The new VertexLabel link targets exist in both locales. I could not run a strict Hugo build locally: the module needs Hugo 0.168.0 and 0.166.0 is installed. The only workflow run at this head, 'Build and deploy site' 39127283628, is action_required and waiting for maintainer approval.
The reason will be displayed to describe this comment to others. Learn more.
Minor: "On 1.7.0 and earlier" does not hold for 1.0.0. In 1.0.0 the endpoint is hugegraph-api/.../api/gremlin/CypherAPI.java. It never throws NotAuthorizedException and never decodes Basic credentials. It forwards whatever Authorization header it gets, including none, to Gremlin Server with doPostRequest(auth, request). A request without the header therefore works when auth is disabled, and Basic credentials are not limited to URL-safe Base64. The header requirement, Base64.getUrlDecoder() and split(":") first appear in the api/cypher/CypherAPI rewrite and are the same in 1.2.0, 1.3.0, 1.5.0 and 1.7.0.
Requested change: write "On 1.2.0 to 1.7.0" here, in CN hugegraph-cypher.md line 34, and in both clients/restful-api/cypher.md notes (line 10).
The reason will be displayed to describe this comment to others. Learn more.
Thanks, you are right that 1.0.0 does not fit. I changed the wording to "1.2.0 to 1.7.0" in all four places you listed (EN and CN hugegraph-cypher.md, EN and CN clients/restful-api/cypher.md) in 2f0b5ba.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: 628170c fixes two of the three points from the previous round: the constraint row now maps uniqueness to UNIQUE IndexLabels and says that primary_keys overwrites, and the English index sentence is scoped to WHERE property predicates on the starting vertex again. One new Minor gap is in the constraint row: a UNIQUE index cannot cover the primary keys of a PRIMARY_KEY label, and step 3 suggests exactly that setup. The open Minor on hugegraph-cypher.md:36 ("1.7.0 and earlier" does not hold for 1.0.0) still applies at this head and is not repeated. Evidence: read the full diff against master 2102662 (13 files) and the 1e5df57..628170c delta (3 files); the 628170c..59ae3bc merge touches no file in this PR. At apache/hugegraph 1.0.0, 1.7.0 and master c2ec57043 I read IndexLabelBuilder.checkPrimaryKeyIndex, GraphIndexTransaction.updateIndex (UNIQUE conflict), HugeVertex.constructEdge (edge non-null keys) and GraphTransaction.checkNonnullProperty; CypherAPI at 1.0.0, 1.2.0 and 1.7.0. At this head scripts/test_versioning.py passes, dist/validate-links.sh passes, and the latest navigation stats match DOCS_NAV_EXPECTED_STATS. The only workflow run at this head, 'Build and deploy site' 39133157795, is action_required and waiting for maintainer approval.
| `CREATE INDEX` / `CREATE CONSTRAINT` | Create property indexes through the [IndexLabel REST API](/docs/clients/restful-api/indexlabel/); uniqueness constraints map to `UNIQUE` IndexLabels (which reject duplicates with a conflict error). Node keys map to non-nullable keys plus a composite `UNIQUE` index. Property existence constraints map to non-nullable keys on [VertexLabels](/docs/clients/restful-api/vertexlabel/) or [EdgeLabels](/docs/clients/restful-api/edgelabel/). Note that `primary_keys` defines vertex identity rather than a constraint—a duplicate `CREATE` overwrites instead of failing |
The reason will be displayed to describe this comment to others. Learn more.
Minor: this refines the node key and uniqueness mapping I suggested in the earlier thread on this line. It does not work when the constrained key is also the label's primary key, which is the setup step 3 (line 77) recommends for idStrategy = "PRIMARY_KEY".
IndexLabelBuilder.checkPrimaryKeyIndex rejects a UNIQUE index on a PRIMARY_KEY vertex label when its fields contain all of the label's primary keys ("No need to build index on properties ..., because they contains all primary keys ..."). The check is the same in 1.0.0, 1.7.0 and master (line 627 on 1.7.0 and master). A reader who puts the Neo4j business key in idFields cannot create the UNIQUE IndexLabel this row names, and keeps only the overwrite on a duplicate.
Requested change: say that a UNIQUE index cannot include all primary keys of a PRIMARY_KEY label. To keep duplicate rejection, use CUSTOMIZE_STRING keyed on the Neo4j node id (as in step 3) with a UNIQUE index on the business key. Mirror this in the CN row (line 29).
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The node key row now says that on a PRIMARY_KEY label a UNIQUE index cannot include all of the label's primary keys, and points to CUSTOMIZE_STRING keyed on the Neo4j node id with a UNIQUE index on the business key when duplicate rejection is needed. Mirrored in the CN row, in 2f0b5ba.
State the supported range as 1.2.0 to 1.7.0 and document that a UNIQUE
index cannot cover all primary keys of a PRIMARY_KEY label, with the
CUSTOMIZE_STRING workaround that keeps duplicate rejection.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Khcp1EMFjG59GuGNef1U73
The reason will be displayed to describe this comment to others. Learn more.
Rechecked at 2f0b5ba084de59d9092666778b9e89d06a5ac59b (2026-10-19). The two latest documentation corrections are independently confirmed: the EN/CN migration rows distinguish PRIMARY_KEY identity from UNIQUE duplicate rejection, including the prohibition on indexing all primary keys; all four authentication notes correctly scope the older behavior to 1.2.0–1.7.0.
Evidence: IndexLabelBuilder.checkPrimaryKeyIndex, CypherAPI at the 1.0.0/1.2.0/1.3.0/1.5.0/1.7.0 tags, and current authentication handling. A separate source cross-check confirmed that CUSTOMIZE_STRING retains supplied identity independently of primary-key-derived identity; the guide already explains node_id and edge endpoint mappings.
Current independent documentation/static-review score: 8.5/10. No new blocking finding across the current 13-file patch. This review did not run Hugo, runtime Cypher queries or a live Neo4j migration, and does not reclassify historical verification as current acceptance. The workflow for this head remains action_required; recommend waiting for current-head CI/acceptance.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The guide reflects the verified Cypher behavior, but the current error envelope and parallel-edge migration semantics still need to be documented. Two inline comments identify these gaps. Evidence: Checked the claims against Apache master at fd8d06c, merge #3259, and SeaTunnel 3.0.0 docs and source at 543f2a5.
[traverser REST APIs](/docs/clients/restful-api/traverser/) or Gremlin instead.
- **Single statement per request** — multi-statement scripts are not supported; send one statement per call.
When a statement fails translation, the response `status.message` contains the transpiler error. If you hit a gap, the Gremlin equivalent is the supported
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Important: Blocking: no. Summary: This only says translation failures appear in status.message, but current master also returns stable status.attributes.errors entries with code, message and hint after #3259. Please document this machine-readable error shape in the REST API reference, or scope this statement to the pinned pre-#3259 commit. Evidence: Current CypherModel.failOf() populates status.attributes.errors, and CypherClient maps failures through CypherErrorMapper; merge #3259 is a0aae8e7.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Important: Blocking: no. Summary: Auto-created EdgeLabels default to SINGLE when SeaTunnel 3.0.0 mappings omit frequency, so parallel Neo4j relationships with the same type and endpoints cannot retain distinct edge identities. Please warn about this and specify frequency = "MULTIPLE" with a stable relationship sortKeys in both language guides. Evidence: SeaTunnel 3.0.0 SchemaManager defaults a missing frequency to SINGLE and requires sort keys for MULTIPLE (commit 543f2a5); HugeGraph edge IDs include sort keys.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The Cypher shortcut omits required vertex data under the assumed schema, and the recommended SeaTunnel path can skip failed records by default. Evidence: GraphTransaction.checkNonnullProperty at 5039e5b and the official SeaTunnel 3.0.0 HugeGraph Sink configuration.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Important: Blocking: no. Summary: Under the assumed schema, name remains non-null because only age and city are nullable; therefore CREATE (a)-[:knows]->(b) cannot create either person vertex, even with AUTOMATIC IDs. Please say the nodes must supply all non-null properties or amend the assumed schema. Evidence: GraphTransaction.checkNonnullProperty rejects missing properties not listed in nullableKeys at the #3289 merge commit 5039e5b; scripts/example.groovy declares person with required name and primaryKeys("name").
The reason will be displayed to describe this comment to others. Learn more.
⚠️ Important: Blocking: no. Summary: The recommended 3.0.0 HugeGraph Sink defaults batch_failure_fallback=true, which logs and skips failed records; it only fails after 500 skips by default (max_insert_errors). Please warn readers to disable fallback or capture and reconcile skipped records and compare row counts before cutover. Evidence: SeaTunnel 3.0.0 HugeGraph Sink documentation lists batch_failure_fallback=true and max_insert_errors=500 as the defaults.
The reason will be displayed to describe this comment to others. Learn more.
Added in 861d6de (EN + CN): warned about SeaTunnel 3.0.0 HugeGraph Sink's batch_failure_fallback=true and default 500-skip limit, advising readers to either disable fallback or reconcile skipped rows before cutover.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: no. Summary: The migration guide misstates the released connector's failure-handling defaults. Evidence: SeaTunnel v3.0.0 HugeGraphOptions.java defines both defaults.
The reason will be displayed to describe this comment to others. Learn more.
⚠️ The released connector source sets batch_failure_fallback to false and max_insert_errors to 0, so an omitted configuration fails fast rather than skipping 500 records. HugeGraphOptions.java at the v3.0.0 tag defines both defaults. Please correct this description in both languages and describe skipping as opt-in. This also corrects the defaults stated in the earlier review comment.
The reason will be displayed to describe this comment to others. Learn more.
Corrected in 0941c1a (EN + CN): documented the fail-fast defaults (batch_failure_fallback=false, max_insert_errors=0) and described record skipping as opt-in.
The reason will be displayed to describe this comment to others. Learn more.
Blocking: yes. Summary: SeaTunnel auto-created EdgeLabels default to SINGLE, so the migration guide still loses parallel Neo4j relationships, and the compatibility page still says the two-vertex shorthand works with AUTOMATIC despite the non-null check.
The earlier review comments below still apply at da365c9; this head does not fix them.
⚠️ Important: Blocking: no. Summary: This only says translation failures appear in status.message, but current master also returns stable status.attributes.errors entries with code, message and hint after #3259. Please document this machine-readable error shape in the REST API reference, or scope this statement to the pinned pre-#3259 commit. Evidence: Current CypherModel.failOf() populates status.attributes.errors, and CypherClient maps failures through CypherErrorMapper; merge #3259 is a0aae8e7. (#499 (comment))
⚠️ Important: Blocking: no. Summary: Auto-created EdgeLabels default to SINGLE when SeaTunnel 3.0.0 mappings omit frequency, so parallel Neo4j relationships with the same type and endpoints cannot retain distinct edge identities. Please warn about this and specify frequency = "MULTIPLE" with a stable relationship sortKeys in both language guides. Evidence: SeaTunnel 3.0.0 SchemaManager defaults a missing frequency to SINGLE and requires sort keys for MULTIPLE (commit 543f2a5); HugeGraph edge IDs include sort keys. (#499 (comment))
Unit and integration test suites cover `CypherApiTest`, `CypherClientTest`, and `CypherOpProcessorTest`.
On a schema with `PRIMARY_KEY` strategy, the shorthand `CREATE (a)-[:knows]->(b)` is rejected because primary keys must be set explicitly; the shorthand works with `AUTOMATIC` id strategy. For `PRIMARY_KEY` schemas, execute the two `CREATE` statements separately.
The reason will be displayed to describe this comment to others. Learn more.
Minor: this line and line 100 say the two-vertex shorthand works with the AUTOMATIC id strategy, but hugegraph-cypher.md line 72 says it is still rejected when the label has non-null properties, as name is under the assumed schema (GraphTransaction.checkNonnullProperty). Add that condition here and on line 100, and mirror it in CN cypher-compatibility.md lines 88-89 and 100.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose of the PR
What is included
Three pages, each with full EN + CN mirrors under
content/{en,cn}/docs/language/:hugegraph-cypher.md— how to use Cypher in HugeGraph: the/cypherREST endpoint, Java client (CypherManager), MATCH/WHERE/RETURN, CREATE/SET/DELETE, aggregation, Gremlin equivalents for unsupported constructs, and an honest Known limitations section (no parameterized queries in released versions — a missing$paramevaluates to null —, noCALLprocedures, single statement per request).cypher-compatibility.md— a verification record of the parameter-binding change: request forms, verified behavior per test, the baseline failure and its fix, and the unverified areas.migrate-from-neo4j.md— what carries over directly, habits that change (strong schema, schema DDL via REST APIs instead of Cypher), and a suggested migration path.All three new pages are registered in
data/docs_nav.json(group tree, section tree, breadcrumb, section children) anddata/version_routes.json(latest only — the pages do not exist in 1.0–1.7).Validation
scripts/hugo.sh build(strict,--panicOnWarning) passes: EN 292 / CN 290 pages.Notes
ASF code PR #3289 was merged into master on 2026-10-08; its organization mirror #238 is closed. The bilingual pages now distinguish merged master support (the 1.8.0 development line) from the latest published 1.7.0 release, retain the verified request/binding boundaries, and explain that the translator's historical TCK percentage is not a HugeGraph end-to-end compatibility rate. The code dependency is merged, so this documentation PR can be reviewed and merged independently.
Conceptual overview
Conceptual documentation overview of Cypher translation, version boundaries and staged Neo4j data migration. This diagram does not establish migration or release acceptance.