imbajin commented on code in PR #499: URL: https://github.com/apache/hugegraph-doc/pull/499#discussion_r4327990764
########## content/en/docs/language/hugegraph-cypher.md: ########## @@ -0,0 +1,198 @@ +--- +title: "HugeGraph Cypher" +linkTitle: "Cypher Query Language" +weight: 2 +--- + +### Overview + +HugeGraph supports [Cypher](https://opencypher.org/), the declarative graph query language originally created by Neo4j and standardized as +[openCypher](https://github.com/opencypher/openCypher). While Gremlin is an imperative traversal language, Cypher lets you describe the graph pattern you want +(`MATCH`, `WHERE`, `RETURN`) and lets the engine decide how to execute it. + +HugeGraph executes Cypher by translating the statement to Gremlin through the [cypher-for-gremlin](https://github.com/opencypher/cypher-for-gremlin) transpiler, +then running the resulting traversal on the TinkerPop stack. This means Cypher support in HugeGraph covers the openCypher 9 surface that the transpiler +implements — see [Known limitations](#known-limitations) below. + +### When to use Cypher vs Gremlin + +| Use Cypher when | Use Gremlin when | +|---|---| +| You are migrating from Neo4j or already know Cypher | You need the full HugeGraph feature surface | +| You want declarative pattern matching (`MATCH (a)-[:KNOWS]->(b)`) | You need fine-grained traversal control, custom steps, or lambdas | +| Your queries are read-mostly patterns and projections | You need graph algorithms, OLAP, or features Cypher does not expose | + +For anything Cypher cannot express, the equivalent Gremlin query always works — examples below show both. + +### Calling the Cypher API + +Cypher statements are submitted to the HugeGraph Server through the REST endpoint: + +```http +GET /graphspaces/{graphspace}/graphs/{graph}/cypher?cypher={statement} +POST /graphspaces/{graphspace}/graphs/{graph}/cypher +``` + +On 1.2.0 to 1.7.0, the endpoint always requires an `Authorization` header (`Basic` or `Bearer`), even when server authentication is disabled — +the credentials are forwarded to the Gremlin Server. On those versions `Basic` credentials must be encoded with URL-safe Base64 (`-` and `_` instead +of `+` and `/`), and the password must not contain `:`. On `master` (1.8.0+), authentication is optional when server auth is disabled +([#3366](https://github.com/apache/hugegraph/pull/3366)), `Basic` credentials use standard RFC 4648 Base64 (as sent by `curl -u`, +[#3290](https://github.com/apache/hugegraph/pull/3290)), and `:` in passwords is supported. +See the [Cypher REST API reference](/docs/clients/restful-api/cypher/) for the full request/response format. + +Example: + +```bash +curl -H "Authorization: Bearer $TOKEN" \ + "http://localhost:8080/graphspaces/DEFAULT/graphs/hugegraph/cypher?cypher=MATCH%20(n:person)%20RETURN%20n.name%20LIMIT%2010" +``` + +From the Java client, use `CypherManager` (see [hugegraph-client](/docs/clients/hugegraph-client/)): + +```java +ResultSet resultSet = hugeClient.cypher().execute("MATCH (n:person) RETURN n.name LIMIT 10"); +``` + +### Basic examples + +The examples below assume a graph with `person` vertices (`name`, `age`, `city` properties) and `knows` edges. +They assume the labels declare `nullableKeys("age", "city")` on `person` and nullable properties on `knows`, and that +`person.age` has a `RANGE` index — for example the schema in `scripts/example.groovy` modified with those nullable keys +plus `schema.indexLabel("personByAge").onV("person").by("age").range().ifNotExist().create()`. A property predicate +in `WHERE` on the starting vertex needs a covering index unless it is an equality on every primary key of the label: +`scripts/example.groovy` indexes `person.city` and `(age, city)` with `SECONDARY` indexes only, so a range comparison such +as `n.age > 30` is rejected with a "not indexed" error until the `RANGE` index exists. +If you load `scripts/example.groovy` first, note that it already seeds the `person` vertices `marko`, `vadas`, `josh` and `peter`; +because the `person` label uses the `PRIMARY_KEY` id strategy, a `CREATE` with one of those names replaces the seeded vertex, +so the create, update and delete examples below use names that the sample data does not contain (`alice`, `bob`, `carol`), +or run them on an empty graph. On a schema without the nullable keys +(the released default marks `age` and `city` non-null on `person`), the create and update examples below fail +the non-null property check: set every non-null property in each statement, or declare the labels with +`nullableKeys` first. If the `person` label uses the `PRIMARY_KEY` id strategy (as it does in `scripts/example.groovy`), the two-vertex +shorthand `CREATE (a)-[:knows]->(b)` is rejected with an execution error reporting that the primary keys must be set +(verified on `master` with [#3289](https://github.com/apache/hugegraph/pull/3289) merged), so the edge example below creates the vertices +first and then matches them. The shorthand works with the `AUTOMATIC` id strategy. Review Comment: ⚠️ 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")`. ########## content/en/docs/language/migrate-from-neo4j.md: ########## @@ -0,0 +1,111 @@ +--- +title: "Migrating from Neo4j" +linkTitle: "Migrating from Neo4j" +weight: 4 +--- + +### Who this page is for + +Neo4j users evaluating HugeGraph. HugeGraph's Cypher coverage is defined by +the [`cypher-for-gremlin`](https://github.com/opencypher/cypher-for-gremlin) +translator and is not 1:1 with Neo4j — see +[Known limitations](/docs/language/hugegraph-cypher/#known-limitations) for what +released HugeGraph versions do, and the +[Cypher compatibility notes](/docs/language/cypher-compatibility/) for the +development-tree verification record and +[HugeGraph Cypher](/docs/language/hugegraph-cypher/) for usage. + +### What carries over directly + +| Neo4j concept | HugeGraph equivalent | +|---|---| +| Property graph model (nodes / relationships / properties) | Same — vertex labels / edge labels / properties | +| Core Cypher: `MATCH`/`WHERE`/`RETURN`/`CREATE`/`SET`/`DELETE` | Works as-is (REST `/cypher` endpoint or Java client `CypherManager`), subject to the schema and index rules below | +| Simple aggregations (`count`/`sum`/`min`/`max`/`avg`) | Works as-is | +| Traversal-heavy queries | Gremlin traversals or the [traverser REST APIs](/docs/clients/restful-api/traverser/) (k-out, shortest path, personalrank, ...) | + +### Habits you need to change + +| In Neo4j | In HugeGraph | +|---|---| +| `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; a `UNIQUE` index cannot include all primary keys of a `PRIMARY_KEY` label (the server rejects it), so to keep duplicate rejection use `CUSTOMIZE_STRING` keyed on the Neo4j node id with a `UNIQUE` index on the business key. 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 | +| Implicit schema (add properties freely) | **Strong schema**: define VertexLabel / EdgeLabel / PropertyKey before writing data | +| Property predicates in `WHERE` need no index | The starting vertex lookup in `WHERE` needs a covering index unless it is an equality on every primary key of the label: create a `SECONDARY` or `RANGE` IndexLabel first, and use `RANGE` for comparisons such as `>` or `<`. Without a covering index the request returns `status.code` 400 with a "not indexed" error | +| Parameterized queries `$param` | Released versions send the raw statement only — a missing binding is inlined as `null` instead of failing (a predicate on it matches no rows, and a write does not reliably store `null`: `SET` removes the property, `CREATE` can store the marker string `" cypher.null"` or fail), so validate values client-side; JSON-bound parameters are available on `master` after [ASF PR #3289](https://github.com/apache/hugegraph/pull/3289), with a fixed limit of 16 top-level bindings | +| `CALL dbms.*` / `CALL algo.*` procedures | Equivalent capabilities live in the [traverser](/docs/clients/restful-api/traverser/), [task](/docs/clients/restful-api/task/), and other REST APIs | +| Driver: Neo4j Bolt driver | [hugegraph-client](/docs/clients/hugegraph-client/) (`CypherManager`) or any HTTP client | +| Transaction boundaries inside a Cypher statement | One statement per request; graph-to-graph data migration uses [Apache SeaTunnel 3.0.0](https://seatunnel.apache.org/download/) (preferred — see below), file-based bulk loads use the [HugeGraph Loader](/docs/quickstart/toolchain/hugegraph-loader/) | + +The latest published release is 1.7.0 as of 2026-10-09; the merged JSON-bound request form is a +`master` feature, not a promise about that release. See the compatibility notes for its validated contract. + +### Suggested migration path + +1. **Inventory your queries**: classify the Cypher in your application against + the [Known limitations](/docs/language/hugegraph-cypher/#known-limitations) + (which describe released behaviour) into + "works as-is / rewrite as Gremlin / switch to a REST API"; the + [compatibility notes](/docs/language/cypher-compatibility/) record only the + development-tree contract. +2. **Create the schema first**: define VertexLabel / EdgeLabel / PropertyKey + and indexes through the schema API — HugeGraph requires the schema to + exist before data is written. +3. **Import data**: the preferred path is + [Apache SeaTunnel 3.0.0](https://seatunnel.apache.org/download/) (released + 2026-09-29) running **Neo4j Source → HugeGraph Sink** directly — no + intermediate file export. REST remains fine for small datasets; the + [HugeGraph Loader](https://github.com/apache/hugegraph-toolchain/tree/master/hugegraph-loader) + stays an alternative for file-based imports. HugeGraph-side setup + (environment, `mappings`, vertex/edge import examples) is covered in the + [Import Graph Data with SeaTunnel Sink guide](/docs/quickstart/toolchain/import/hugegraph-seatunnel-connector/). + + The [SeaTunnel 3.0.0 connector docs](https://seatunnel.apache.org/docs/3.0.0/introduction/about/) document + what to rely on: + - [Neo4j Source](https://seatunnel.apache.org/docs/3.0.0/connectors/source/Neo4j/) reads Cypher + query results with explicit field schemas; 3.0.0 adds multi-table reads via `tables_configs`. + - [HugeGraph Sink](https://seatunnel.apache.org/docs/3.0.0/connectors/sink/HugeGraph/) is Review Comment: ⚠️ 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](https://seatunnel.apache.org/docs/3.0.0/connectors/sink/HugeGraph/) lists `batch_failure_fallback=true` and `max_insert_errors=500` as the defaults. -- 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]
