diff --git a/.gitignore b/.gitignore index c6739ae5a..2641bbfe1 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,7 @@ pnpm-lock.yaml .claude/ CLAUDE.md .release-tracking/ + +# MemGQL docs redesign — local verification scratchpad (do not commit) +UNVERIFIED-CLAIMS.local.md +PROPOSAL.md diff --git a/next.config.mjs b/next.config.mjs index a2a126c27..1dec3b87a 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -19,6 +19,57 @@ export default withNextra({ reactStrictMode: true, async redirects() { return [ + // MemGQL docs restructure (Idea-B sections) + { + source: '/memgraph-zero/memgql/quick-start', + destination: '/memgraph-zero/memgql/get-started/quick-start', + permanent: true + }, + { + source: '/memgraph-zero/memgql/complete', + destination: '/memgraph-zero/memgql/get-started/docker-compose', + permanent: true + }, + { + source: '/memgraph-zero/memgql/use-cases', + destination: '/memgraph-zero/memgql/overview/use-cases', + permanent: true + }, + { + source: '/memgraph-zero/memgql/use-cases/:path*', + destination: '/memgraph-zero/memgql/overview/use-cases/:path*', + permanent: true + }, + { + source: '/memgraph-zero/memgql/features', + destination: '/memgraph-zero/memgql/overview/editions', + permanent: true + }, + { + source: '/memgraph-zero/memgql/connect', + destination: '/memgraph-zero/memgql/connectors', + permanent: true + }, + { + source: '/memgraph-zero/memgql/connect/:path*', + destination: '/memgraph-zero/memgql/connectors/:path*', + permanent: true + }, + { + source: '/memgraph-zero/memgql/multiple-graphs', + destination: '/memgraph-zero/memgql/guides/querying-across-backends', + permanent: true + }, + { + source: '/memgraph-zero/memgql/licensing', + destination: '/memgraph-zero/memgql/reference/licensing', + permanent: true + }, + { + source: '/memgraph-zero/memgql/changelog', + destination: '/memgraph-zero/memgql/reference/changelog', + permanent: true + }, { source: '/cypher-manual/graph-algorithms', destination: '/advanced-algorithms', diff --git a/pages/memgraph-zero.mdx b/pages/memgraph-zero.mdx index d81a296ad..7a97f1390 100644 --- a/pages/memgraph-zero.mdx +++ b/pages/memgraph-zero.mdx @@ -46,24 +46,24 @@ releases. Memgraph Zero solves specific problems that teams face when data is scattered across systems and compliance boundaries: -- **[Public-Private Data](/memgraph-zero/memgql/use-cases/public-private)** — +- **[Public-Private Data](/memgraph-zero/memgql/overview/use-cases/public-private)** — Keep sensitive data sovereign while querying it alongside public knowledge graphs. Private customer records stay in PostgreSQL; public catalogs live in Memgraph. One GQL query joins both without moving regulated data. -- **[Enterprise Context Sharing](/memgraph-zero/memgql/use-cases/enterprise-context)** — +- **[Enterprise Context Sharing](/memgraph-zero/memgql/overview/use-cases/enterprise-context)** — Share canonical context across departments without forcing every team into the same database. -- **[Distributed Compute](/memgraph-zero/memgql/use-cases/distributed)** — +- **[Distributed Compute](/memgraph-zero/memgql/overview/use-cases/distributed)** — Spread graph computation across multiple nodes for workloads that exceed a single instance. -- **[Agentic Data Access](/memgraph-zero/memgql/use-cases/agentic)** — +- **[Agentic Data Access](/memgraph-zero/memgql/overview/use-cases/agentic)** — Give AI agents a single semantic layer to discover and query any data in the organization using standard GQL. -See all [use cases](/memgraph-zero/memgql/use-cases) for working examples and +See all [use cases](/memgraph-zero/memgql/overview/use-cases) for working examples and Docker Compose setups you can run yourself. ## Why Zero ETL matters diff --git a/pages/memgraph-zero/memgql.mdx b/pages/memgraph-zero/memgql.mdx index 7c05326d7..4048c3db6 100644 --- a/pages/memgraph-zero/memgql.mdx +++ b/pages/memgraph-zero/memgql.mdx @@ -18,22 +18,19 @@ Bolt-compatible driver. The long-term vision for MemGQL is to cover all data source types — structured, semi-structured and unstructured — essentially serving as a semantic layer -where agents can find any data behind a single interface. +where agents can find any data behind a single interface. It is the first +component of [Memgraph Zero](/memgraph-zero), Memgraph's "connect, don't +collect" product line. ![MemGQL Reference Architecture](/pages/memgraph-zero/memgql/memgql_ref_architecture.png) -New to MemGQL? Start with the [Quick Start](/memgraph-zero/memgql/quick-start) guide -to get up and running in minutes. Once you're set up, check out the -[Use Cases](/memgraph-zero/memgql/use-cases) to see real-world applications, and -explore the [Features](/memgraph-zero/memgql/features) to understand what MemGQL can -do. Learn how to [Connect](/memgraph-zero/memgql/connect) to your data sources and -review the [Multiple Graphs](/memgraph-zero/memgql/multiple-graphs) support for -querying across heterogeneous backends. For local development, check out the [Docker -Compose](/memgraph-zero/memgql/complete) setup. When you're ready to dive deeper, the -[Reference](/memgraph-zero/memgql/reference) documentation covers all the syntax -details. Review the [Licensing](/memgraph-zero/memgql/licensing) information for terms -of use, and check the [Changelog](/memgraph-zero/memgql/changelog) to stay updated on -the latest improvements. +## Start here + +- **[Quick Start](/memgraph-zero/memgql/get-started/quick-start)** — run MemGQL against Memgraph in minutes. +- **[How it works](/memgraph-zero/memgql/overview/how-it-works)** — the architecture: translation, mappings, connectors, and routing. +- **[Connectors](/memgraph-zero/memgql/connectors)** — every supported backend and exactly which GQL features each one supports. +- **[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends)** — federate queries over multiple backends, with or without `USE`. +- **[Reference](/memgraph-zero/memgql/reference)** — the full GQL feature support, statements, and configuration. ## Questions & Feedback diff --git a/pages/memgraph-zero/memgql/_meta.ts b/pages/memgraph-zero/memgql/_meta.ts index ed520042c..9ebb7b570 100644 --- a/pages/memgraph-zero/memgql/_meta.ts +++ b/pages/memgraph-zero/memgql/_meta.ts @@ -1,11 +1,7 @@ export default { - "quick-start": "Quick Start", - "use-cases": "Use Cases", - "features": "Features", - "connect": "Connect", - "multiple-graphs": "Multiple Graphs", - "complete": "Docker Compose", + "overview": "Overview", + "get-started": "Get started", + "connectors": "Connectors", + "guides": "Guides", "reference": "Reference", - "licensing": "Licensing", - "changelog": "Changelog", } diff --git a/pages/memgraph-zero/memgql/connect.mdx b/pages/memgraph-zero/memgql/connect.mdx deleted file mode 100644 index c4f144bcb..000000000 --- a/pages/memgraph-zero/memgql/connect.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: Connect -description: MemGQL connector details and configuration. ---- - -# Connect to: - -- [ClickHouse](/memgraph-zero/memgql/connect/clickhouse) -- [DuckDB](/memgraph-zero/memgql/connect/duckdb) -- [Iceberg](/memgraph-zero/memgql/connect/iceberg) -- [Memgraph](/memgraph-zero/memgql/connect/memgraph) -- [MySQL](/memgraph-zero/memgql/connect/mysql) -- [Neo4j](/memgraph-zero/memgql/connect/neo4j) -- [Oracle](/memgraph-zero/memgql/connect/oracle) -- [Pinot](/memgraph-zero/memgql/connect/pinot) -- [PostgreSQL](/memgraph-zero/memgql/connect/postgres) - -## Multi-Connector - -Connect to multiple backends simultaneously. See the [Quick Start](/memgraph-zero/memgql/quick-start#multi-connection-mode) for details. diff --git a/pages/memgraph-zero/memgql/connect/_meta.ts b/pages/memgraph-zero/memgql/connect/_meta.ts deleted file mode 100644 index 0f9781a07..000000000 --- a/pages/memgraph-zero/memgql/connect/_meta.ts +++ /dev/null @@ -1,11 +0,0 @@ -export default { - "clickhouse": "to Clickhouse", - "duckdb": "to DuckDB", - "iceberg": "to Iceberg", - "memgraph": "to Memgraph", - "neo4j": "to Neo4j", - "oracle": "to Oracle", - "postgres": "to PostgreSQL", - "mysql": "to MySQL", - "pinot": "to Pinot", -} diff --git a/pages/memgraph-zero/memgql/connect/memgraph.mdx b/pages/memgraph-zero/memgql/connect/memgraph.mdx deleted file mode 100644 index a5fbb5acf..000000000 --- a/pages/memgraph-zero/memgql/connect/memgraph.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -title: Memgraph -description: Connect MemGQL to Memgraph. ---- - -# Memgraph - -MemGQL supports two Memgraph connector modes: - -- **`memgraph`** — passthrough, forwards queries as-is (Cypher) -- **`memgraph-gql`** — translates GQL to Cypher before execution - -## 1. Start Memgraph - -```bash -docker network create memgql-net - -docker run -d --rm \ - --name memgraph-dev \ - --network memgql-net \ - -p 7687:7687 \ - memgraph/memgraph-mage:3.10.1 \ - --log-level=TRACE --also-log-to-stderr -``` - -## 2. Start MemGQL (GQL mode) - -```bash -docker run --rm \ - --name memgql \ - --network memgql-net \ - --stop-timeout 2 \ - -p 7688:7688 \ - --env CONNECTOR_TYPE=memgraph-gql \ - --env MEMGRAPH_URI=memgraph-dev:7687 \ - --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ - memgraph/memgql:latest -``` - -For passthrough mode, use `CONNECTOR_TYPE=memgraph` instead. - -## 3. Connect - -```bash -mgconsole --port 7688 -``` - -## 4. Seed data - -```gql -INSERT - (alice:Person {name: "Alice", age: 30}), - (bob:Person {name: "Bob", age: 25}), - (acme:Company {name: "Acme Corp"}), - (alice)-[:KNOWS]->(bob), - (alice)-[:WORKS_AT {role: "Engineer"}]->(acme); -``` - -## 5. Query - -```gql -MATCH (p:Person) RETURN p.name, p.age; -``` - -```gql -MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; -``` - -```gql -MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; -``` - -For environment variables, see [Reference](../reference.mdx#memgraph-memgraph-memgraph-gql). - -## Supported GQL features - -GQL-specific syntax (INSERT, LOCAL_DATETIME, etc.) only works on `memgraph-gql`; the plain `memgraph` connector is Cypher passthrough. - -| Feature | Memgraph | -|-----------------------------------------------|----------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Multi-MATCH (cross-join) | ✓ | -| `OPTIONAL MATCH` | ✓ | -| `WITH` pipeline boundary | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | -| Chained `WITH … WITH …` | ✓ | -| Whole-node `WITH n` carry-through | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| Untyped edge `()-[]->(b)` | ✓ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | -| `INTERSECT` / `EXCEPT` | ✗ | -| Quantified path `(){m,n}` — bounded | ✓ | -| Quantified path `(){m,}` — unbounded | ✓ | -| Shortest-path (`ALL SHORTEST` / `SHORTEST k`) | ✓ | -| Path binding `MATCH p = (…) RETURN p` | ✓ | -| Whole-node `RETURN n` | ✓ | -| Map projections `RETURN n {.a, .b}` | ✓ | -| `IN` list membership `WHERE x IN [...]` | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | -| `collect()` aggregate | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | -| `COUNT(DISTINCT …)` | ✓ | -| Arithmetic `+ - * / %` | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | -| `COALESCE`, `NULLIF` | ✓ | -| Temporals (`date`, `LOCAL_DATETIME`, …) | ✓ | -| `INSERT (a {…}) RETURN a.x` | ✓ | -| `DELETE` / `DETACH DELETE` | ✓ | -| `SET` / `REMOVE` (property update / delete) | ✓ | diff --git a/pages/memgraph-zero/memgql/connect/neo4j.mdx b/pages/memgraph-zero/memgql/connect/neo4j.mdx deleted file mode 100644 index 01ae5006f..000000000 --- a/pages/memgraph-zero/memgql/connect/neo4j.mdx +++ /dev/null @@ -1,113 +0,0 @@ ---- -title: Neo4j -description: Connect MemGQL to Neo4j. ---- - -# Neo4j - -MemGQL supports two Neo4j connector modes: - -- **`neo4j`** — passthrough, forwards queries as-is (Cypher) -- **`neo4j-gql`** — translates GQL to Cypher before execution - -## 1. Start Neo4j - -```bash -docker network create memgql-net - -docker run -d --rm \ - --name neo4j-dev \ - --network memgql-net \ - -p 7474:7474 \ - -p 7697:7687 \ - --env NEO4J_AUTH=neo4j/password \ - neo4j:5 -``` - -## 2. Start MemGQL (GQL mode) - -```bash -docker run --rm \ - --name memgql \ - --network memgql-net \ - --stop-timeout 2 \ - -p 7688:7688 \ - --env CONNECTOR_TYPE=neo4j-gql \ - --env NEO4J_URI=neo4j-dev:7687 \ - --env NEO4J_USER=neo4j \ - --env NEO4J_PASS=password \ - --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ - memgraph/memgql:latest -``` - -For passthrough mode, use `CONNECTOR_TYPE=neo4j` instead. - -## 3. Connect - -```bash -mgconsole --port 7688 -``` - -## 4. Seed data - -```gql -INSERT - (alice:Person {name: "Alice", age: 30}), - (bob:Person {name: "Bob", age: 25}), - (acme:Company {name: "Acme Corp"}), - (alice)-[:KNOWS]->(bob), - (alice)-[:WORKS_AT {role: "Engineer"}]->(acme); -``` - -## 5. Query - -```gql -MATCH (p:Person) RETURN p.name, p.age; -``` - -```gql -MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; -``` - -```gql -MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; -``` - -For environment variables, see [Reference](../reference.mdx#neo4j-neo4j-neo4j-gql). - -## Supported GQL features - -GQL-specific syntax (INSERT, LOCAL_DATETIME, etc.) only works on `neo4j-gql`; the plain `neo4j` connector is Cypher passthrough. - -| Feature | Neo4j | -|-----------------------------------------------|-------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Multi-MATCH (cross-join) | ✓ | -| `OPTIONAL MATCH` | ✓ | -| `WITH` pipeline boundary | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | -| Chained `WITH … WITH …` | ✓ | -| Whole-node `WITH n` carry-through | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| Untyped edge `()-[]->(b)` | ✓ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | -| `INTERSECT` / `EXCEPT` | ✗ | -| Quantified path `(){m,n}` — bounded | ✓ | -| Quantified path `(){m,}` — unbounded | ✓ | -| Shortest-path (`ALL SHORTEST` / `SHORTEST k`) | ✓ | -| Path binding `MATCH p = (…) RETURN p` | ✓ | -| Whole-node `RETURN n` | ✓ | -| Map projections `RETURN n {.a, .b}` | ✓ | -| `IN` list membership `WHERE x IN [...]` | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | -| `collect()` aggregate | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | -| `COUNT(DISTINCT …)` | ✓ | -| Arithmetic `+ - * / %` | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | -| `COALESCE`, `NULLIF` | ✓ | -| Temporals (`date`, `LOCAL_DATETIME`, …) | ✓ | -| `INSERT (a {…}) RETURN a.x` | ✓ | -| `DELETE` / `DETACH DELETE` | ✓ | -| `SET` / `REMOVE` (property update / delete) | ✓ | diff --git a/pages/memgraph-zero/memgql/connectors.mdx b/pages/memgraph-zero/memgql/connectors.mdx new file mode 100644 index 000000000..084852113 --- /dev/null +++ b/pages/memgraph-zero/memgql/connectors.mdx @@ -0,0 +1,96 @@ +--- +title: Connectors +description: Every MemGQL backend connector and the exact GQL features each one supports. +--- + +# Connectors + +A **connector** tells MemGQL how to reach a backend and which language to translate +GQL into. Connectors fall into three tiers: + +- **Graph** — [Memgraph](/memgraph-zero/memgql/connectors/memgraph), + [Neo4j](/memgraph-zero/memgql/connectors/neo4j). GQL is translated to Cypher (or + forwarded unchanged). Full query surface. +- **Relational** — [PostgreSQL](/memgraph-zero/memgql/connectors/postgres), + [MySQL](/memgraph-zero/memgql/connectors/mysql), + [Oracle](/memgraph-zero/memgql/connectors/oracle), + [DuckDB](/memgraph-zero/memgql/connectors/duckdb). GQL is translated to SQL over a + [mapping](/memgraph-zero/memgql/guides/mapping). Reads and writes. +- **Analytical** — [ClickHouse](/memgraph-zero/memgql/connectors/clickhouse), + [Iceberg](/memgraph-zero/memgql/connectors/iceberg), + [Apache Pinot](/memgraph-zero/memgql/connectors/pinot). Also GQL-to-SQL, but + read-oriented and with a narrower verified surface. + +## Choosing a backend + +- **Need writes (`INSERT` / `DELETE`)?** Use a Graph or Relational backend. Pinot is + read-only. +- **Need the full graph surface** (variable-length paths, shortest path, `SET`, + temporals)? Use a Graph backend (Memgraph, Neo4j). +- **Querying analytics / a lakehouse you already run?** ClickHouse, Iceberg, or Pinot + — read patterns over your existing tables. +- **Joining across backends?** Verified end-to-end on Memgraph, PostgreSQL, MySQL, + and DuckDB today — see [Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends). + +## Feature support + +Each `✓` is backed by a passing query in the cross-backend test corpus. + +**Legend:** `✓` supported · `✗` returns an actionable error (never silently wrong) · +`RO` read-only (writes rejected) · `—` not yet verified on this backend. + +| Feature | Memgraph | Neo4j | PostgreSQL | MySQL | Oracle | DuckDB | ClickHouse | Iceberg | Pinot | +|---|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:|:--:| +| `MATCH` / `WHERE` / `RETURN` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Multiple `MATCH` clauses | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `OPTIONAL MATCH` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `WITH` (chain / `DISTINCT` / chained) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Whole-node `WITH n` carry-through | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Typed edge `(a)-[r:R]->(b)` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Untyped edge `()-[]->()` 1 | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | +| Quantified path `(){m,n}` — bounded | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Quantified path `(){m,}` — unbounded 1 | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | +| Shortest path (`ALL`/`ANY SHORTEST`, `SHORTEST k`) 1 | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | +| Whole-node `RETURN n` / `RETURN r` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| Map projections `RETURN n {.a, .b}` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Connection-less `RETURN 1` (liveness) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | +| `IN` list membership | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `collect()` / `collect_list()` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `count`, `sum`, `avg`, `min`, `max` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `COUNT(DISTINCT …)` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Arithmetic `+ - * / %` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `CASE WHEN … THEN … ELSE … END` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `COALESCE`, `NULLIF` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| Temporals (`date`, `datetime`, …) | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | +| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | — | — | — | +| `INTERSECT` / `EXCEPT` | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | +| `INSERT (a {…})` / `… RETURN` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ 2 | ✓ 3 | RO | +| `DELETE` | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ 2 | ✓ 3 | RO | +| `DETACH DELETE` | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | RO | +| `SET` / `REMOVE` (property update / delete) | ✓ | ✓ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | RO | + +1 Untyped edges, unbounded variable-length paths, and shortest-path run +natively on Cypher backends. On SQL backends they return an actionable error pointing +you at the typed/bounded form or a Cypher backend. +2 ClickHouse `DELETE` is emitted as `ALTER TABLE … DELETE`. +3 Iceberg `DELETE` is emitted without a table alias (Trino requirement). + +## Cross-backend joins + +A single query can span backends; MemGQL splits it, runs each part on its backend, and +hash-joins the results in memory. See +[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends). + +| Cross-backend join support | Status | +|---|---| +| Memgraph, PostgreSQL, MySQL, DuckDB | Verified end-to-end | +| Neo4j, Oracle, ClickHouse, Iceberg, Pinot | Wired — same code path, broader live verification in progress | +| Whole-node return across the join boundary | Not supported — return individual properties (`m.name`), not `m` | + +## Multi-connector mode + +Run several backends at once and manage them with statements at runtime. See +[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends) and the +[Statements reference](/memgraph-zero/memgql/reference/statements). diff --git a/pages/memgraph-zero/memgql/connectors/_meta.ts b/pages/memgraph-zero/memgql/connectors/_meta.ts new file mode 100644 index 000000000..adfcf830e --- /dev/null +++ b/pages/memgraph-zero/memgql/connectors/_meta.ts @@ -0,0 +1,14 @@ +export default { + "-- graph": { type: "separator", title: "Graph" }, + "memgraph": "Memgraph", + "neo4j": "Neo4j", + "-- relational": { type: "separator", title: "Relational" }, + "postgres": "PostgreSQL", + "mysql": "MySQL", + "oracle": "Oracle", + "duckdb": "DuckDB", + "-- analytical": { type: "separator", title: "Analytical" }, + "clickhouse": "ClickHouse", + "iceberg": "Iceberg", + "pinot": "Apache Pinot", +} diff --git a/pages/memgraph-zero/memgql/connect/clickhouse.mdx b/pages/memgraph-zero/memgql/connectors/clickhouse.mdx similarity index 71% rename from pages/memgraph-zero/memgql/connect/clickhouse.mdx rename to pages/memgraph-zero/memgql/connectors/clickhouse.mdx index b90c49d1e..0371f930f 100644 --- a/pages/memgraph-zero/memgql/connect/clickhouse.mdx +++ b/pages/memgraph-zero/memgql/connectors/clickhouse.mdx @@ -7,7 +7,7 @@ description: Connect MemGQL to ClickHouse. The ClickHouse connector (`CONNECTOR_TYPE=clickhouse`) translates GQL queries into ClickHouse-dialect SQL and executes them via the ClickHouse HTTP interface. -It requires a [mapping file](../quick-start.mdx#mapping-file) that maps graph +It requires a [mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to ClickHouse tables. ## 1. Start ClickHouse @@ -95,17 +95,8 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` -For environment variables, see [Reference](../reference.mdx#clickhouse-clickhouse). +For environment variables, see [Reference](../reference/configuration.mdx#clickhouse-clickhouse). -## Supported GQL features +## Feature support -| Feature | ClickHouse | -|-----------------------------------------------|------------| -| `MATCH (n:Label) RETURN n.prop` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| `ORDER BY` / `LIMIT` | ✓ | -| `DISTINCT` | ✓ | -| `INSERT (a {…})` | ✓ | -| `DELETE` (via `ALTER TABLE … DELETE`) | ✓ | -| Boolean literals as 1/0 | ✓ | +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. diff --git a/pages/memgraph-zero/memgql/connect/duckdb.mdx b/pages/memgraph-zero/memgql/connectors/duckdb.mdx similarity index 50% rename from pages/memgraph-zero/memgql/connect/duckdb.mdx rename to pages/memgraph-zero/memgql/connectors/duckdb.mdx index b4a506b9b..56ee6efea 100644 --- a/pages/memgraph-zero/memgql/connect/duckdb.mdx +++ b/pages/memgraph-zero/memgql/connectors/duckdb.mdx @@ -7,7 +7,7 @@ description: Connect MemGQL to DuckDB. The DuckDB connector (`CONNECTOR_TYPE=duckdb`) translates GQL queries into SQL and executes them against an embedded DuckDB instance. It requires a -[mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to +[mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to relational tables. DuckDB runs in-process (no separate server needed), making it ideal for local @@ -73,44 +73,14 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` -For environment variables, see [Reference](../reference.mdx#duckdb-duckdb). - -## Supported GQL features - -| Feature | DuckDB | -|-----------------------------------------------|--------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Multiple `MATCH` clauses in one query | ✓ | -| `OPTIONAL MATCH` | ✓ | -| `WITH` clause (chain query steps) | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | -| Multiple chained `WITH` steps | ✓ | -| Pass a whole node through `WITH n` | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| Untyped edge `()-[]->(b)` | ✗ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | -| Quantified path `(){m,n}` — bounded | ✓ | -| Map projections `RETURN n {.a, .b}` | ✓ | -| `IN` list membership `WHERE x IN [...]` | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | -| `collect()` aggregate | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | -| `COUNT(DISTINCT …)` | ✓ | -| Arithmetic `+ - * / %` | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | -| `COALESCE`, `NULLIF` | ✓ | -| `INSERT (a {…}) RETURN a.x` | ✓ | -| `DELETE` | ✓ | -| `SET` / `REMOVE` (property update / delete) | ✗ | -| `DETACH DELETE` | ✗ | -| `INTERSECT` / `EXCEPT` | ✗ | -| Quantified path `(){m,}` — unbounded | ✗ | -| Shortest-path (`ALL SHORTEST` / `SHORTEST k`) | ✗ | +For environment variables, see [Reference](../reference/configuration.mdx#duckdb-duckdb). + +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. ## Known limitations - **Unbounded variable-length paths** (`()-[*]->()`) are rejected. Bound the depth (`{1,5}`) or run the query against a Cypher backend. - **`FOR x IN [...]` (UNWIND-style)** is rejected with an actionable error. Cypher backends (Memgraph, Neo4j) handle this syntax natively. - **Path variables on variable-length patterns** — `MATCH p = (a){1,3}(b) RETURN p` is not supported. Drop the `p =` binding (or query a Cypher backend) and `RETURN` the individual nodes / edges instead. -- **`RETURN n`** returns the node's column values rather than a single structured node object. For a structured result, use a map projection: `RETURN n {.id, .name} AS info`. diff --git a/pages/memgraph-zero/memgql/connect/iceberg.mdx b/pages/memgraph-zero/memgql/connectors/iceberg.mdx similarity index 71% rename from pages/memgraph-zero/memgql/connect/iceberg.mdx rename to pages/memgraph-zero/memgql/connectors/iceberg.mdx index 23b8ad267..7c0e3024d 100644 --- a/pages/memgraph-zero/memgql/connect/iceberg.mdx +++ b/pages/memgraph-zero/memgql/connectors/iceberg.mdx @@ -9,7 +9,7 @@ The Iceberg connector (`CONNECTOR_TYPE=iceberg`) translates GQL queries into Trino-dialect SQL with fully-qualified table references (`catalog.schema.table`) and executes them against Iceberg tables via Trino's REST API. It requires a -[mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to +[mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to Iceberg tables. ## 1. Start Trino with Iceberg @@ -93,16 +93,8 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` -For environment variables, see [Reference](../reference.mdx#iceberg-iceberg). +For environment variables, see [Reference](../reference/configuration.mdx#iceberg-iceberg). -## Supported GQL features +## Feature support -| Feature | Iceberg / Trino | -|-----------------------------------------------|-----------------| -| `MATCH (n:Label) RETURN n.prop` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| `ORDER BY` / `LIMIT` | ✓ | -| `DISTINCT` | ✓ | -| `INSERT (a {…})` | ✓ | -| `DELETE` (no alias — Trino requirement) | ✓ | +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. diff --git a/pages/memgraph-zero/memgql/connectors/memgraph.mdx b/pages/memgraph-zero/memgql/connectors/memgraph.mdx new file mode 100644 index 000000000..035167dc1 --- /dev/null +++ b/pages/memgraph-zero/memgql/connectors/memgraph.mdx @@ -0,0 +1,77 @@ +--- +title: Memgraph +description: Connect MemGQL to Memgraph. +--- + +# Memgraph + +MemGQL supports two Memgraph connector modes: + +- **`memgraph`** — passthrough, forwards queries as-is (Cypher) +- **`memgraph-gql`** — translates GQL to Cypher before execution + +## 1. Start Memgraph + +```bash +docker network create memgql-net + +docker run -d --rm \ + --name memgraph-dev \ + --network memgql-net \ + -p 7687:7687 \ + memgraph/memgraph-mage:3.10.1 \ + --log-level=TRACE --also-log-to-stderr +``` + +## 2. Start MemGQL (GQL mode) + +```bash +docker run --rm \ + --name memgql \ + --network memgql-net \ + --stop-timeout 2 \ + -p 7688:7688 \ + --env CONNECTOR_TYPE=memgraph-gql \ + --env MEMGRAPH_URI=memgraph-dev:7687 \ + --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ + memgraph/memgql:latest +``` + +For passthrough mode, use `CONNECTOR_TYPE=memgraph` instead. + +## 3. Connect + +```bash +mgconsole --port 7688 +``` + +## 4. Seed data + +```gql +INSERT + (alice:Person {name: "Alice", age: 30}), + (bob:Person {name: "Bob", age: 25}), + (acme:Company {name: "Acme Corp"}), + (alice)-[:KNOWS]->(bob), + (alice)-[:WORKS_AT {role: "Engineer"}]->(acme); +``` + +## 5. Query + +```gql +MATCH (p:Person) RETURN p.name, p.age; +``` + +```gql +MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; +``` + +```gql +MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; +``` + +For environment variables, see [Reference](../reference/configuration.mdx#memgraph-memgraph-memgraph-gql). + +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. diff --git a/pages/memgraph-zero/memgql/connect/mysql.mdx b/pages/memgraph-zero/memgql/connectors/mysql.mdx similarity index 57% rename from pages/memgraph-zero/memgql/connect/mysql.mdx rename to pages/memgraph-zero/memgql/connectors/mysql.mdx index 368c56793..f175e82d9 100644 --- a/pages/memgraph-zero/memgql/connect/mysql.mdx +++ b/pages/memgraph-zero/memgql/connectors/mysql.mdx @@ -7,7 +7,7 @@ description: Connect MemGQL to MySQL. The MySQL connector (`CONNECTOR_TYPE=mysql`) translates GQL queries into MySQL-dialect SQL and executes them against MySQL 8.0+. It requires a -[mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to +[mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to relational tables. ## 1. Start MySQL @@ -104,44 +104,14 @@ MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; - Aliased single-table `DELETE` is emitted as the multi-table form `DELETE alias FROM table AS alias WHERE …` (MySQL 8.0+ requirement). -For environment variables, see [Reference](../reference.mdx#mysql-mysql). - -## Supported GQL features - -| Feature | MySQL | -|-----------------------------------------------|-------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Multiple `MATCH` clauses in one query | ✓ | -| `OPTIONAL MATCH` | ✓ | -| `WITH` clause (chain query steps) | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | -| Multiple chained `WITH` steps | ✓ | -| Pass a whole node through `WITH n` | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| Untyped edge `()-[]->(b)` | ✗ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | -| Quantified path `(){m,n}` — bounded | ✓ | -| Map projections `RETURN n {.a, .b}` | ✓ | -| `IN` list membership `WHERE x IN [...]` | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | -| `collect()` aggregate | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | -| `COUNT(DISTINCT …)` | ✓ | -| Arithmetic `+ - * / %` | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | -| `COALESCE`, `NULLIF` | ✓ | -| `INSERT (a {…})` (MySQL has no `RETURNING`) | ✓ | -| `DELETE` | ✓ | -| `SET` / `REMOVE` (property update / delete) | ✗ | -| `DETACH DELETE` | ✗ | -| `INTERSECT` / `EXCEPT` | ✗ | -| Quantified path `(){m,}` — unbounded | ✗ | -| Shortest-path (`ALL SHORTEST` / `SHORTEST k`) | ✗ | +For environment variables, see [Reference](../reference/configuration.mdx#mysql-mysql). + +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. ## Known limitations - **Unbounded variable-length paths** (`()-[*]->()`) are rejected. Bound the depth (`{1,5}`) or run the query against a Cypher backend. - **`FOR x IN [...]` (UNWIND-style)** is rejected with an actionable error. Cypher backends (Memgraph, Neo4j) handle this syntax natively. - **Path variables on variable-length patterns** — `MATCH p = (a){1,3}(b) RETURN p` is not supported. Drop the `p =` binding (or query a Cypher backend) and `RETURN` the individual nodes / edges instead. -- **`RETURN n`** returns the node's column values rather than a single structured node object. For a structured result, use a map projection: `RETURN n {.id, .name} AS info`. diff --git a/pages/memgraph-zero/memgql/connectors/neo4j.mdx b/pages/memgraph-zero/memgql/connectors/neo4j.mdx new file mode 100644 index 000000000..68ed6a8dc --- /dev/null +++ b/pages/memgraph-zero/memgql/connectors/neo4j.mdx @@ -0,0 +1,80 @@ +--- +title: Neo4j +description: Connect MemGQL to Neo4j. +--- + +# Neo4j + +MemGQL supports two Neo4j connector modes: + +- **`neo4j`** — passthrough, forwards queries as-is (Cypher) +- **`neo4j-gql`** — translates GQL to Cypher before execution + +## 1. Start Neo4j + +```bash +docker network create memgql-net + +docker run -d --rm \ + --name neo4j-dev \ + --network memgql-net \ + -p 7474:7474 \ + -p 7697:7687 \ + --env NEO4J_AUTH=neo4j/password \ + neo4j:5 +``` + +## 2. Start MemGQL (GQL mode) + +```bash +docker run --rm \ + --name memgql \ + --network memgql-net \ + --stop-timeout 2 \ + -p 7688:7688 \ + --env CONNECTOR_TYPE=neo4j-gql \ + --env NEO4J_URI=neo4j-dev:7687 \ + --env NEO4J_USER=neo4j \ + --env NEO4J_PASS=password \ + --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ + memgraph/memgql:latest +``` + +For passthrough mode, use `CONNECTOR_TYPE=neo4j` instead. + +## 3. Connect + +```bash +mgconsole --port 7688 +``` + +## 4. Seed data + +```gql +INSERT + (alice:Person {name: "Alice", age: 30}), + (bob:Person {name: "Bob", age: 25}), + (acme:Company {name: "Acme Corp"}), + (alice)-[:KNOWS]->(bob), + (alice)-[:WORKS_AT {role: "Engineer"}]->(acme); +``` + +## 5. Query + +```gql +MATCH (p:Person) RETURN p.name, p.age; +``` + +```gql +MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; +``` + +```gql +MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; +``` + +For environment variables, see [Reference](../reference/configuration.mdx#neo4j-neo4j-neo4j-gql). + +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. diff --git a/pages/memgraph-zero/memgql/connect/oracle.mdx b/pages/memgraph-zero/memgql/connectors/oracle.mdx similarity index 93% rename from pages/memgraph-zero/memgql/connect/oracle.mdx rename to pages/memgraph-zero/memgql/connectors/oracle.mdx index 94a832970..b4b856f5e 100644 --- a/pages/memgraph-zero/memgql/connect/oracle.mdx +++ b/pages/memgraph-zero/memgql/connectors/oracle.mdx @@ -8,7 +8,7 @@ description: Connect MemGQL to Oracle Database (incl. Oracle Database Free 23ai) The Oracle connector (`CONNECTOR_TYPE=oracle`) translates GQL queries into Oracle-dialect SQL and executes them against Oracle Database 19c+, including [Oracle Database Free 23ai](https://www.oracle.com/database/free/). It requires -a [mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to +a [mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to relational tables. The driver is [oracle-rs](https://crates.io/crates/oracle-rs), a **pure-Rust** @@ -117,6 +117,10 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. + ## Dialect notes - Positional bind variables use Oracle's native `:1`, `:2`, … form. @@ -144,4 +148,4 @@ CONNECT ora AS ora_conn; USE CONNECTION ora_conn MATCH (n:Person) RETURN n.name LIMIT 5; ``` -For environment variables, see [Reference](../reference.mdx#oracle-oracle). +For environment variables, see [Reference](../reference/configuration.mdx#oracle-oracle). diff --git a/pages/memgraph-zero/memgql/connect/pinot.mdx b/pages/memgraph-zero/memgql/connectors/pinot.mdx similarity index 84% rename from pages/memgraph-zero/memgql/connect/pinot.mdx rename to pages/memgraph-zero/memgql/connectors/pinot.mdx index c1415dc8c..0b77ad6b2 100644 --- a/pages/memgraph-zero/memgql/connect/pinot.mdx +++ b/pages/memgraph-zero/memgql/connectors/pinot.mdx @@ -93,12 +93,8 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` -For environment variables, see [Reference](../reference.mdx#apache-pinot-pinot). +For environment variables, see [Reference](../reference/configuration.mdx#apache-pinot-pinot). -## Supported GQL features +## Feature support -| Feature | Pinot | -|-----------------------------------------------|-------| -| `MATCH (n:Label) RETURN n.prop` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. diff --git a/pages/memgraph-zero/memgql/connect/postgres.mdx b/pages/memgraph-zero/memgql/connectors/postgres.mdx similarity index 51% rename from pages/memgraph-zero/memgql/connect/postgres.mdx rename to pages/memgraph-zero/memgql/connectors/postgres.mdx index 5022295dd..4357fb942 100644 --- a/pages/memgraph-zero/memgql/connect/postgres.mdx +++ b/pages/memgraph-zero/memgql/connectors/postgres.mdx @@ -7,7 +7,7 @@ description: Connect MemGQL to PostgreSQL. The PostgreSQL connector (`CONNECTOR_TYPE=postgres`) translates GQL queries into SQL and executes them against PostgreSQL. It requires a -[mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to +[mapping file](../guides/mapping.mdx#mapping-file) that maps graph patterns to relational tables. ## 1. Start PostgreSQL @@ -88,44 +88,14 @@ MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN p.name, c.name; MATCH (a:Person)-[:KNOWS]->(b:Person) RETURN a.name, b.name; ``` -For environment variables, see [Reference](../reference.mdx#postgresql-postgres). - -## Supported GQL features - -| Feature | Postgres | -|-----------------------------------------------|----------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | -| Multiple `MATCH` clauses in one query | ✓ | -| `OPTIONAL MATCH` | ✓ | -| `WITH` clause (chain query steps) | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | -| Multiple chained `WITH` steps | ✓ | -| Pass a whole node through `WITH n` | ✓ | -| Typed edge `(a)-[r:R]->(b)` | ✓ | -| Untyped edge `()-[]->(b)` | ✗ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | -| Quantified path `(){m,n}` — bounded | ✓ | -| Map projections `RETURN n {.a, .b}` | ✓ | -| `IN` list membership `WHERE x IN [...]` | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | -| `collect()` aggregate | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | -| `COUNT(DISTINCT …)` | ✓ | -| Arithmetic `+ - * / %` | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | -| `COALESCE`, `NULLIF` | ✓ | -| `INSERT (a {…}) RETURN a.x` | ✓ | -| `DELETE` | ✓ | -| `SET` / `REMOVE` (property update / delete) | ✗ | -| `DETACH DELETE` | ✗ | -| `INTERSECT` / `EXCEPT` | ✗ | -| Quantified path `(){m,}` — unbounded | ✗ | -| Shortest-path (`ALL SHORTEST` / `SHORTEST k`) | ✗ | +For environment variables, see [Reference](../reference/configuration.mdx#postgresql-postgres). + +## Feature support + +See the [feature support matrix](/memgraph-zero/memgql/connectors#feature-support) for the GQL features this connector supports. ## Known limitations - **Unbounded variable-length paths** (`()-[*]->()`) are rejected. Bound the depth (`{1,5}`) or run the query against a Cypher backend. - **`FOR x IN [...]` (UNWIND-style)** is rejected with an actionable error. Cypher backends (Memgraph, Neo4j) handle this syntax natively. - **Path variables on variable-length patterns** — `MATCH p = (a){1,3}(b) RETURN p` is not supported. Drop the `p =` binding (or query a Cypher backend) and `RETURN` the individual nodes / edges instead. -- **`RETURN n`** returns the node's column values rather than a single structured node object. For a structured result, use a map projection: `RETURN n {.id, .name} AS info`. diff --git a/pages/memgraph-zero/memgql/features.mdx b/pages/memgraph-zero/memgql/features.mdx deleted file mode 100644 index b2455a47e..000000000 --- a/pages/memgraph-zero/memgql/features.mdx +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Features -description: MemGQL Community and Enterprise feature comparison. ---- - -# Features - -| Feature | Community | [Enterprise](https://memgraph.com/contact-us) | -|--------------------------------------------------------|-----------|-----------------------------------------------| -| GQL to Cypher translation | Yes | Yes | -| GQL to SQL translation | Yes | Yes | -| Bolt protocol | Yes | Yes | -| **Connectors** | | | -| [Memgraph](/memgraph-zero/memgql/connect/memgraph) | Yes | Yes | -| [Neo4j](/memgraph-zero/memgql/connect/neo4j) | Yes | Yes | -| [PostgreSQL](/memgraph-zero/memgql/connect/postgres) | Yes | Yes | -| [DuckDB](/memgraph-zero/memgql/connect/duckdb) | Yes | Yes | -| [Iceberg](/memgraph-zero/memgql/connect/iceberg) | Yes | Yes | -| [ClickHouse](/memgraph-zero/memgql/connect/clickhouse) | Yes | Yes | -| [MySQL](/memgraph-zero/memgql/connect/mysql) | Yes | Yes | -| [Pinot](/memgraph-zero/memgql/connect/pinot) | Yes | Yes | -| [Oracle](/memgraph-zero/memgql/connect/oracle) | Yes | Yes | -| **Multi-Connection Mode** | Yes | Yes | -| Max connectors | 2 | Unlimited | -| Max simultaneous connections | 2 | Unlimited | -| **Agentic Capabilities** | | | -| MCP Server | Yes | Yes | -| Structured2Graph Agent to create mappings | Yes | Yes | diff --git a/pages/memgraph-zero/memgql/get-started/_meta.ts b/pages/memgraph-zero/memgql/get-started/_meta.ts new file mode 100644 index 000000000..6908cbf0b --- /dev/null +++ b/pages/memgraph-zero/memgql/get-started/_meta.ts @@ -0,0 +1,4 @@ +export default { + "quick-start": "Quick Start", + "docker-compose": "Docker Compose", +} diff --git a/pages/memgraph-zero/memgql/complete.mdx b/pages/memgraph-zero/memgql/get-started/docker-compose.mdx similarity index 98% rename from pages/memgraph-zero/memgql/complete.mdx rename to pages/memgraph-zero/memgql/get-started/docker-compose.mdx index 56baa08f6..df181a563 100644 --- a/pages/memgraph-zero/memgql/complete.mdx +++ b/pages/memgraph-zero/memgql/get-started/docker-compose.mdx @@ -102,7 +102,7 @@ Save the following as `docker-compose.yml`: ```yaml services: memgql: - image: ${MEMGQL_IMAGE:-memgraph/memgql:0.6.1} + image: ${MEMGQL_IMAGE:-memgraph/memgql:latest} container_name: memgql ports: - "7688:7688" @@ -246,7 +246,7 @@ Wait for all containers to become healthy: docker compose ps ``` -You should see all eight services running: `memgraph`, `memgql`, `memgql-init`, +You should see all seven services running: `memgraph`, `memgql`, `memgql-init`, `lab`, `postgres`, `memgql-mcp`, and `structured2graph`. The `memgql-init` container registers both connectors and exits — this is expected. diff --git a/pages/memgraph-zero/memgql/get-started/quick-start.mdx b/pages/memgraph-zero/memgql/get-started/quick-start.mdx new file mode 100644 index 000000000..46ff11575 --- /dev/null +++ b/pages/memgraph-zero/memgql/get-started/quick-start.mdx @@ -0,0 +1,157 @@ +--- +title: Quick Start +description: Get started with MemGQL quickly. +--- + +# Quick Start + +MemGQL is a federated GQL (ISO/IEC 39075) query engine that translates GQL queries +into backend-native languages and executes them across graph databases. +Clients connect via the Bolt protocol (port 7688) using any Bolt-compatible driver. + +## Prerequisites + +- [Docker](https://docs.docker.com/get-started/get-docker/) +- [mgconsole](https://github.com/memgraph/mgconsole) (Memgraph Bolt CLI client) + +## Quick Start: Memgraph + MemGQL + +### 1. Create a Docker network + +```bash +docker network create memgql-net +``` + +### 2. Start Memgraph + +```bash +docker run -d --rm \ + --name memgraph-dev \ + --network memgql-net \ + -p 7687:7687 \ + memgraph/memgraph-mage:3.10.1 \ + --log-level=TRACE --also-log-to-stderr +``` + +### 3. Start MemGQL + +```bash +docker run --rm \ + --name memgql \ + --network memgql-net \ + --stop-timeout 2 \ + -p 7688:7688 \ + --env CONNECTOR_TYPE=memgraph-gql \ + --env MEMGRAPH_URI=memgraph-dev:7687 \ + --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ + memgraph/memgql:latest +``` + +### 4. Connect with mgconsole + +```bash +mgconsole --port 7688 +``` + +### 5. Seed some data + +```gql +INSERT + (lana:Developer {name: "Lana", level: "senior", yoe: 12}), + (marco:Developer {name: "Marco", level: "mid", yoe: 5}), + (priya:Developer {name: "Priya", level: "senior", yoe: 9}), + (rs:Language {name: "Rust", releaseYear: 2010}), + (go:Language {name: "Go", releaseYear: 2009}), + (ts:Language {name: "TypeScript", releaseYear: 2012}), + (acme:Startup {name: "Acme Labs", funding: 4200000}), + (nova:Startup {name: "Nova AI", funding: 18500000}), + (lana)-[:WRITES {since: 2018}]->(rs), + (lana)-[:WRITES {since: 2021}]->(go), + (marco)-[:WRITES {since: 2022}]->(ts), + (priya)-[:WRITES {since: 2019}]->(rs), + (priya)-[:WRITES {since: 2020}]->(ts), + (lana)-[:MENTORS]->(marco), + (priya)-[:MENTORS]->(marco), + (lana)-[:EMPLOYED_AT {role: "CTO"}]->(acme), + (marco)-[:EMPLOYED_AT {role: "Backend Engineer"}]->(nova), + (priya)-[:EMPLOYED_AT {role: "Tech Lead"}]->(nova); +``` + +### 6. Run GQL queries + +Count all nodes in the graph: + +```gql +MATCH () RETURN count(*); +``` + +Return developers and their experience: + +```gql +MATCH (d:Developer) RETURN d.name, d.yoe; +``` + +Filter with WHERE inside the pattern (GQL syntax): + +```gql +MATCH (d:Developer WHERE d.yoe > 8) RETURN d.name, d.level; +``` + +Label expression with IS keyword: + +```gql +MATCH (s IS Startup) RETURN s.name, s.funding; +``` + +OR label expression — match multiple labels at once: + +```gql +MATCH (n:Language|Startup) RETURN n; +``` + +Edge pattern with direction and type: + +```gql +MATCH (:Developer)-[w:WRITES]->(lang:Language) RETURN lang.name, w.since; +``` + +Edge with WHERE clause: + +```gql +MATCH (:Developer)-[w:WRITES WHERE w.since < 2020]->(lang:Language) RETURN lang.name; +``` + +Path variable binding: + +```gql +MATCH p = (:Developer)-[:MENTORS]->(:Developer) RETURN p; +``` + +Two-hop traversal — who mentors someone employed at a startup: + +```gql +MATCH (senior:Developer)-[:MENTORS]->(junior:Developer)-[:EMPLOYED_AT]->(s:Startup) +RETURN senior.name, junior.name, s.name; +``` + +Variable-length path (quantified path pattern): + +```gql +MATCH (d:Developer {name: "Lana"})-[:MENTORS]->{1,3}(mentee:Developer) RETURN mentee.name; +``` + +## Environment variables + +See [Configuration & env vars](/memgraph-zero/memgql/reference/configuration) for the +full list of environment variables and connector-specific settings. + +## Next steps + +- **Connect a relational backend** — every relational connector needs a + [mapping](/memgraph-zero/memgql/guides/mapping) from graph patterns to tables. See the + [Connectors](/memgraph-zero/memgql/connectors) pages for per-backend setup. +- **Query across several backends at once** — run in `multi` mode and route queries + automatically or with `USE`. See [Querying across + backends](/memgraph-zero/memgql/guides/querying-across-backends). +- **Run the full stack locally** (Memgraph + PostgreSQL + MCP server) with [Docker + Compose](/memgraph-zero/memgql/get-started/docker-compose). diff --git a/pages/memgraph-zero/memgql/guides/_meta.ts b/pages/memgraph-zero/memgql/guides/_meta.ts new file mode 100644 index 000000000..4cf28cb2f --- /dev/null +++ b/pages/memgraph-zero/memgql/guides/_meta.ts @@ -0,0 +1,5 @@ +export default { + "mapping": "Mapping data to a graph", + "querying-across-backends": "Querying across backends", + "agents": "Using MemGQL with agents", +} diff --git a/pages/memgraph-zero/memgql/guides/agents.mdx b/pages/memgraph-zero/memgql/guides/agents.mdx new file mode 100644 index 000000000..ea941e975 --- /dev/null +++ b/pages/memgraph-zero/memgql/guides/agents.mdx @@ -0,0 +1,52 @@ +--- +title: Using MemGQL with agents +description: Use MemGQL as a semantic layer for AI agents via the MCP server. +--- + +# Using MemGQL with agents + +MemGQL gives an AI agent a single GQL endpoint over every backend it's connected to. +Instead of teaching the agent where each dataset lives and how to query it, you point +it at MemGQL: it discovers the available graph with `SHOW SCHEMA` and queries +relational, graph, and lakehouse backends with one language. + +## MCP server + +The MemGQL MCP server exposes MemGQL over the [Model Context +Protocol](https://modelcontextprotocol.io), so any MCP-capable agent can run GQL +against any backend wired into MemGQL. + +```bash +docker run --rm \ + --name memgql-mcp \ + --network memgql-net \ + -p 8000:8000 \ + --env MCP_TRANSPORT=streamable-http \ + --env MEMGQL_URL=bolt://memgql:7688 \ + memgraph/memgql-mcp:0.2.0 +``` + +The server connects to MemGQL over Bolt (`MEMGQL_URL`) and serves MCP over HTTP on +port 8000. It's also wired into the [Docker Compose +stack](/memgraph-zero/memgql/get-started/docker-compose), which brings up MemGQL, a +backend, and the MCP server together. + +## Discovery with `SHOW SCHEMA` + +`SHOW SCHEMA` is the discoverability surface for agents: it returns the labels, +properties, and relationship types MemGQL knows per source. An agent calls it to learn +what it can query — and the same index drives [automatic +routing](/memgraph-zero/memgql/guides/querying-across-backends#automatic-routing-use-free), +so an agent can issue `USE`-free queries and let MemGQL pick the backend. + +```gql +SHOW SCHEMA; +``` + +## Generating mappings with structured2graph + +For relational backends, an agent (or you) needs a +[mapping](/memgraph-zero/memgql/guides/mapping). The `structured2graph` agent inspects +an existing relational schema and generates the mapping JSON for you. It ships as a +container in the [Docker Compose stack](/memgraph-zero/memgql/get-started/docker-compose), +writing the mapping to a shared volume that MemGQL can load with `ADD MAPPING`. diff --git a/pages/memgraph-zero/memgql/guides/mapping.mdx b/pages/memgraph-zero/memgql/guides/mapping.mdx new file mode 100644 index 000000000..3683f71ce --- /dev/null +++ b/pages/memgraph-zero/memgql/guides/mapping.mdx @@ -0,0 +1,118 @@ +--- +title: Mapping data to a graph +description: Map relational tables to graph nodes and relationships so GQL patterns translate to SQL. +--- + +# Mapping data to a graph + +A graph database already knows what a node and a relationship are. A relational +backend (PostgreSQL, MySQL, Oracle, DuckDB, ClickHouse, Iceberg, Apache Pinot) does +not — so MemGQL needs a **mapping** that says which table backs each node label, +which table backs each relationship type, and which columns are the join keys. + +With a mapping in place, a pattern like +`MATCH (p:Person)-[:WORKS_AT]->(c:Company)` is translated into a SQL join across the +`persons`, `works_at`, and `companies` tables. Mappings are required for every +relational connector and for [`multi` +mode](/memgraph-zero/memgql/guides/querying-across-backends); Cypher backends +(Memgraph, Neo4j) don't use one. + +## Mapping file + +A mapping is a JSON document with two top-level arrays, `nodes` and `edges`: + +```json +{ + "nodes": [ /* NodeMapping objects */ ], + "edges": [ /* EdgeMapping objects */ ] +} +``` + +MemGQL loads it either from the path in the `MAPPING_FILE` environment variable at +startup, or via the `ADD MAPPING FROM ''` statement at runtime — both +apply the same validation. A mapping with any required field missing is rejected +before the server serves queries against it. + +### Node mapping fields + +| Field | Type | Required | Description | +|--------------|-------------------------|----------|-------------| +| `label` | string | yes | GQL node label (e.g. `"Person"`). | +| `table` | string | yes | Backend table or view backing this label. | +| `id_column` | string | yes | Primary key column. Surfaces as GQL `id(n)` and joins across edges. | +| `properties` | object (string→string) | no | Map from GQL property name → backend column name. Properties not listed pass through unchanged (`p.name` → column `name`). | + +### Edge mapping fields + +| Field | Type | Required | Description | +|------------------|-------------------------|----------|-------------| +| `rel_type` | string | yes | GQL relationship type (e.g. `"KNOWS"`). | +| `table` | string | yes | Junction / association table backing this edge type. | +| `id_column` | string | yes | Per-edge primary key. **Required since v0.6.** Carried through the recursive CTE's visited-edge set to enforce trail semantics on variable-length traversal. | +| `source_column` | string | yes | FK column pointing to the source node's `id_column`. | +| `target_column` | string | yes | FK column pointing to the target node's `id_column`. | +| `source_label` | string | yes | Label of the source node (must match a `label` in `nodes`). | +| `target_label` | string | yes | Label of the target node. | +| `properties` | object (string→string) | no | Map from GQL property name → column name on the edge table. | + +### Connector-specific fields + +- **Iceberg** also accepts `catalog` and `schema_name` to fully qualify the table + reference (defaults: `"iceberg"`, `"default"`). +- **ClickHouse** also accepts `database` (default: `"default"`). + +## Identifiers are matched exactly + +Labels, relationship types, and property names are matched **case-sensitively** +against the mapping. A query that says `MATCH (:person)` does **not** match a mapping +that declares `"label": "Person"` — the casing must agree. Spell the `label`, +`rel_type`, and property names in your mapping exactly as you write them in queries. +(Exact matching also lets MemGQL route USE-free queries reliably — see +[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends).) + +## Example + +```json +{ + "nodes": [ + { + "label": "Person", + "table": "persons", + "id_column": "id", + "properties": { "name": "full_name", "age": "age" } + }, + { + "label": "Company", + "table": "companies", + "id_column": "id" + } + ], + "edges": [ + { + "rel_type": "KNOWS", + "table": "knows", + "id_column": "id", + "source_column": "from_id", + "target_column": "to_id", + "source_label": "Person", + "target_label": "Person" + }, + { + "rel_type": "WORKS_AT", + "table": "works_at", + "id_column": "id", + "source_column": "person_id", + "target_column": "company_id", + "source_label": "Person", + "target_label": "Company" + } + ] +} +``` + +Without `MAPPING_FILE`, a default `Person`/`Company` mapping (the shape above) is used. + +## Generating a mapping + +The `structured2graph` agent can generate a mapping JSON from an existing relational +schema — see [Using MemGQL with agents](/memgraph-zero/memgql/guides/agents). diff --git a/pages/memgraph-zero/memgql/guides/querying-across-backends.mdx b/pages/memgraph-zero/memgql/guides/querying-across-backends.mdx new file mode 100644 index 000000000..687847f12 --- /dev/null +++ b/pages/memgraph-zero/memgql/guides/querying-across-backends.mdx @@ -0,0 +1,196 @@ +--- +title: Querying across backends +description: Federate GQL queries over multiple backends — automatic schema routing, explicit USE, and composite queries. +--- + +# Querying across backends + +When MemGQL is connected to more than one backend, a query can target one of them or +span several. There are two ways the target is chosen: + +- **Automatic routing** (the default) — MemGQL infers the backend from the labels, + relationship types, and properties the query mentions. No `USE` needed. +- **Explicit `USE`** — you name the graph. This always wins and is the escape hatch + when a query is ambiguous or targets a backend automatic routing can't resolve. + +Both require [`multi` mode](#setting-up-multi-mode), where you register backends as a +**graph catalog** and manage them at runtime. + +## Setting up multi mode + +Start MemGQL with `CONNECTOR_TYPE=multi`, then register connectors and graphs: + +```gql +ADD CONNECTOR neo4j_prod TYPE neo4j URI 'bolt://neo4j:7687' USER 'neo4j' PASSWORD 'secret'; +ADD CONNECTOR pg_warehouse TYPE postgres URI 'postgresql://pg:5432/dw'; + +-- A graph is a friendly name bound to a connector (and optional remote db + mapping) +ADD GRAPH social ON CONNECTOR neo4j_prod GRAPH neo4j; +ADD GRAPH warehouse ON CONNECTOR pg_warehouse MAPPING company_mapping READ ONLY; +``` + +See the [Statements reference](/memgraph-zero/memgql/reference/statements) for the full +catalog grammar. + +## Automatic routing (USE-free) + +Once backends are registered, just query — MemGQL routes by what the query mentions. +In a catalog where `Person` lives on both a Postgres `transactional` graph and a +Memgraph `social` graph, but `name` is only a Postgres column and `FRIEND_OF` is only +a Memgraph relationship: + +```gql +-- property narrows to Postgres (only it has `name`) +MATCH (p:Person) RETURN p.name; + +-- relationship type narrows to Memgraph (only it has FRIEND_OF) +MATCH (me:Person {id: 1})-[:FRIEND_OF]->(f:Person) RETURN f.id; +``` + +A single query can also **span** backends. MemGQL splits it at the `MATCH` boundary, +runs each part on its backend, and hash-joins the results in memory: + +```gql +-- USE-free federated join +MATCH (me:Person {id: 1})-[:FRIEND_OF]->(f:Person) +MATCH (fp:Person)-[:ORDERED]->(prod:`Product`) WHERE fp.id = f.id +RETURN fp.name AS friend, prod.name AS item; +``` + +`UNION` branches route independently, too: + +```gql +MATCH (p:Person)-[:ORDERED]->(prod:`Product`) WHERE p.id = 1 RETURN prod.id +UNION +MATCH (:`Product` {id: 1})-[:SIMILAR_TO]->(s:`Product`) RETURN s.id; +``` + +### How routing decides + +MemGQL builds a **global schema index** — labels, relationship types, and properties +per source — from relational [mappings](/memgraph-zero/memgql/guides/mapping) and from +live introspection of Cypher backends. For each query it intersects the signals the +query mentions against that index: + +- **Exactly one** candidate source → routes there. +- **Two or more** candidates → returns an error naming the candidates and how to + disambiguate (session defaults never break the tie). +- **Zero** candidates → returns an error naming the unknown label / type / property. +- **No signals** (e.g. `MATCH (n)`, `RETURN 1`) → not routed; the session default + applies. + +### When you still need `USE` + +| Situation | What happens | Fix | +|---|---|---| +| Same label on two backends, nothing else narrows | Ambiguous — error lists candidates | Add a distinguishing property to the query, or name the graph with `USE` | +| `MATCH (n)` with no label | Not routed (no signal); on SQL backends a label-less match errors | Add a label, or `USE` a graph | +| Backend not in the index (multi-tenant remote db, introspection failed) | Not routed | `USE` the graph explicitly | +| One `MATCH` pattern spanning two backends | Error asking you to split it | Split into one `MATCH` per backend (as in the federated-join example above) | + +### Make routing reliable + +Routing is only as good as the schema index. To get clean, unambiguous routing: + +- **Declare distinguishing properties** in relational mappings — a property that + exists on only one backend lets MemGQL narrow to it. (SQL schema comes entirely from + the mapping; undeclared columns can't narrow.) +- **Keep labels and relationship types distinct** across backends where you can. +- **Run `REFRESH SCHEMA`** after a backend's schema changes, so introspection picks up + new labels and properties. + +### Inspect the schema index + +`SHOW SCHEMA` prints what MemGQL knows per source — the labels, properties, and +relationship types it routes on. It's the first thing to run when routing doesn't go +where you expected, and it's the discoverability surface agents use to learn the +catalog. + +```gql +SHOW SCHEMA; +SHOW SCHEMA FOR social; +REFRESH SCHEMA; +``` + +## Explicit `USE` and composite queries + +Naming the graph bypasses inference. Use it for ambiguous queries, multi-tenant +backends, or just for explicitness: + +```gql +USE social MATCH (p:Person) RETURN p.name; +USE warehouse MATCH (c:Company) WHERE c.revenue > 1000000 RETURN c.name; +``` + +A focused multi-graph query chains `USE` clauses; variables bind across parts: + +```gql +USE social +MATCH (p:Person)-[:WORKS_AT]->(c:Company) +USE warehouse +MATCH (co:Company) +WHERE co.name = c.name AND co.revenue > 1000000 +RETURN p.name AS person, c.name AS company, co.revenue AS revenue; +``` + +The GQL standard composite operators combine query branches, and each branch can target +a different graph: + +```gql +-- UNION: people from both environments +USE social MATCH (p:Person) RETURN p.email AS email +UNION +USE dev MATCH (p:Person) RETURN p.email AS email; + +-- INTERSECT: people present in both +USE social MATCH (p:Person) RETURN p.email AS email +INTERSECT +USE dev MATCH (p:Person) RETURN p.email AS email; + +-- EXCEPT: in production but not yet in dev +USE social MATCH (p:Person) RETURN p.email AS email +EXCEPT +USE dev MATCH (p:Person) RETURN p.email AS email; +``` + +## Cross-graph rules + +1. **No pushed joins across backends.** Cross-graph joins always materialize both + sides locally and hash-join; the engine never pushes a join across backends. +2. **Property-based join keys.** Join keys must use node/edge properties — internal + IDs are backend-specific and not comparable across connectors. +3. **Whole-node returns don't cross the boundary.** Return individual properties + (`m.name`), not the whole node `m`, across a federated join. +4. **Single-graph writes.** A mutation in a multi-graph query must target one graph; + writes spanning backends are rejected. +5. **Compatible columns.** All branches of a composite query must produce the same + number of columns, in the same order, with compatible types. + +See the [cross-backend join status](/memgraph-zero/memgql/connectors#cross-backend-joins) +for which backends are verified end-to-end today. + +## Managing the catalog + +```gql +SHOW GRAPHS; -- list registered graphs +SHOW GRAPHS ON CONNECTOR neo4j_prod; -- filter by connector +SHOW GRAPH social; -- details for one graph + +ALTER GRAPH social SET READ ONLY; -- change access mode +ALTER GRAPH social SET CONNECTOR neo4j_staging; -- rebind (e.g. failover) +ALTER GRAPH knowledge SET MAPPING updated_mapping; + +UNADD GRAPH social; -- remove from catalog only +DROP GRAPH analytics; -- remove from catalog AND drop on backend +``` + +`CREATE GRAPH` both registers a graph and creates it on the backend: + +```gql +CREATE GRAPH analytics ON CONNECTOR memgraph_dev; + +CREATE GRAPH typed_graph { + NODE Person ({name STRING, age INT}), + EDGE KNOWS ()-[]->() +} ON CONNECTOR neo4j_prod; +``` diff --git a/pages/memgraph-zero/memgql/multiple-graphs.mdx b/pages/memgraph-zero/memgql/multiple-graphs.mdx deleted file mode 100644 index af8114c7d..000000000 --- a/pages/memgraph-zero/memgql/multiple-graphs.mdx +++ /dev/null @@ -1,293 +0,0 @@ ---- -title: Multiple Graphs & Composite Queries -description: Query across multiple graphs and backends using the graph catalog and composite queries. ---- - -# Multiple Graphs & Composite Queries - -MemGQL introduces a **graph catalog** that makes graphs first-class entities. Rather than specifying connectors and connections in every query, you register graphs once and reference them by name. This enables seamless multi-graph queries across heterogeneous backends using standard ISO GQL composite clauses. - -## Where the catalog DSL works - -The catalog statements (`ADD CONNECTOR`, `ADD GRAPH`, `SHOW GRAPHS`, `SHOW CONNECTORS`, `DROP GRAPH`, `USE `, …) are available in **`CONNECTOR_TYPE=multi`** mode. Single-backend modes (`memgraph-gql`, `neo4j-gql`, `postgres`, `mysql`, `oracle`, `duckdb`, `clickhouse`, `iceberg`, `pinot`) connect to one backend configured via env vars and don't expose the catalog. - -| Statement | `multi` | Cypher single-backend | SQL single-backend | -|---|---|---|---| -| `SHOW GRAPHS` / `SHOW CONNECTORS` / `SHOW MAPPINGS` | ✓ | ✗ | ✗ | -| `ADD CONNECTOR` / `ADD GRAPH` / `CONNECT` | ✓ | ✗ | ✗ | -| `CREATE GRAPH ` | ✓ (catalog entry) | ✓ (forwarded as `CREATE DATABASE `) | ✗ | -| `DROP GRAPH ` | ✓ | ✗ | ✗ | -| `TRUNCATE ` | ✓ | ✓ (forwarded as `MATCH (n) DETACH DELETE n`) | ✗ | -| `USE …` | ✓ (routes via catalog) | ✓ (treated as backend database) | ✗ | - -If you need graph management today, run MemGQL in `multi` mode. - -## Graph Registration - -Before querying across graphs, register them in the catalog using `ADD GRAPH` or `CREATE GRAPH`: - -```gql --- Register existing graphs on different backends -ADD GRAPH social ON CONNECTOR neo4j_prod GRAPH neo4j; -ADD GRAPH events ON CONNECTOR clickhouse_logs READ ONLY; -ADD GRAPH warehouse ON CONNECTOR postgres_dw MAPPING company_mapping READ ONLY; -ADD GRAPH dev ON CONNECTOR memgraph_dev; -``` - -Each graph entry stores: -- **Name**: Local catalog identifier -- **Connector**: Which connector hosts this graph -- **Remote graph**: Backend-specific graph/database name (optional) -- **Mapping**: Schema mapping for relational connectors (optional) -- **Access mode**: `READ WRITE` (default) or `READ ONLY` - -## Single Graph Queries - -Once registered, use graphs by name without specifying connectors: - -```gql --- Query the social graph (resolves to neo4j_prod) -USE social MATCH (p:Person) RETURN p.name; - --- Query the events graph (read-only ClickHouse) -USE events MATCH (e:Event) WHERE e.ts > '2025-01-01' RETURN e; - --- Query the warehouse with mapping translation -USE warehouse MATCH (c:Company) WHERE c.revenue > 1000000 RETURN c; -``` - -The engine resolves the graph name to its bound connector and executes the query on the appropriate backend. - -## Focused Multi-Graph Queries - -A single linear query can chain multiple `USE` clauses. Variables bind across parts, enabling joins across backends: - -```gql --- Find people in the social graph who work at high-revenue companies in the warehouse -USE social -MATCH (p:Person)-[:WORKS_AT]->(c:Company) -USE warehouse -MATCH (co:Company) -WHERE co.name = c.name AND co.revenue > 1000000 -RETURN p.name AS person, c.name AS company, co.revenue AS revenue; -``` - -Execution flow: -1. The `USE social` part executes on `neo4j_prod`, returning `(p, c)` bindings -2. The `USE warehouse` part executes on `postgres_dw`, using `c.name` values as filters -3. Results are joined locally and returned - -Another example correlating social connections with event logs: - -```gql --- Find friends of Alice who made purchases -USE social -MATCH (alice:Person {name: 'Alice'})-[:KNOWS]->(friend:Person) -USE events -MATCH (e:Event) -WHERE e.user_email = friend.email AND e.type = 'purchase' -RETURN friend.email AS email, e.item AS item, e.amount AS amount; -``` - -## Composite Queries Across Graphs - -The GQL standard defines composite expressions combining query branches with `UNION`, `INTERSECT`, and `EXCEPT`. Each branch can target a different graph. - -### UNION - -Combine results from multiple graphs: - -```gql --- All people from both production and dev environments -USE social MATCH (p:Person) RETURN p.name AS name, p.email AS email -UNION -USE dev MATCH (p:Person) RETURN p.name AS name, p.email AS email; - --- Events from ClickHouse combined with activity logs from Postgres -USE events -MATCH (e:Event) WHERE e.ts > '2025-06-01' -RETURN e.type AS activity, e.user_email AS user, e.ts AS timestamp -UNION ALL -USE warehouse -MATCH (a:ActivityLog) WHERE a.date > '2025-06-01' -RETURN a.action AS activity, a.employee_email AS user, a.date AS timestamp; -``` - -### INTERSECT - -Find entities present in both graphs: - -```gql --- People who exist in both production and dev -USE social MATCH (p:Person) RETURN p.email AS email -INTERSECT -USE dev MATCH (p:Person) RETURN p.email AS email; - --- Companies appearing in both social graph and data warehouse -USE social -MATCH (c:Company) RETURN c.name AS company_name -INTERSECT -USE warehouse -MATCH (c:Company) RETURN c.name AS company_name; -``` - -### EXCEPT - -Find entities in one graph but not another: - -```gql --- People in production not yet migrated to dev -USE social MATCH (p:Person) RETURN p.email AS email -EXCEPT -USE dev MATCH (p:Person) RETURN p.email AS email; - --- Events in ClickHouse with no matching warehouse activity log -USE events -MATCH (e:Event) WHERE e.type = 'purchase' -RETURN e.user_email AS user, e.ts AS timestamp -EXCEPT -USE warehouse -MATCH (a:ActivityLog) WHERE a.action = 'purchase' -RETURN a.employee_email AS user, a.date AS timestamp; -``` - -### Mixed Composites - -Combine multiple composite operations: - -```gql --- People in production OR dev, but NOT in the warehouse's inactive list -USE social MATCH (p:Person) RETURN p.email AS email -UNION -USE dev MATCH (p:Person) RETURN p.email AS email -EXCEPT -USE warehouse -MATCH (p:Person) WHERE p.status = 'inactive' -RETURN p.email AS email; -``` - -## Graph Introspection - -View all registered graphs: - -```gql -SHOW GRAPHS; -``` - -``` -+------------+---------------+----------------+--------------+------------------+---------------+---------------+------------+ -| name | connector | connector_type | remote | mapping | mapping_nodes | mapping_edges | access | -+------------+---------------+----------------+--------------+------------------+---------------+---------------+------------+ -| social | neo4j_prod | neo4j | neo4j | — | — | — | READ WRITE | -| events | ch_logs | clickhouse | — | — | — | — | READ ONLY | -| warehouse | pg_warehouse | postgres | — | company_mapping | 2 | 2 | READ ONLY | -| dev | mg_dev | memgraph | — | — | — | — | READ WRITE | -+------------+---------------+----------------+--------------+------------------+---------------+---------------+------------+ -``` - -Filter by connector: - -```gql -SHOW GRAPHS ON CONNECTOR neo4j_prod; -``` - -View details for a specific graph: - -```gql -SHOW GRAPH social; -``` - -## Graph Lifecycle Management - -### Creating Graphs - -`CREATE GRAPH` both registers the graph and creates it on the remote backend: - -```gql --- Create an empty graph on a specific backend -CREATE GRAPH analytics ON CONNECTOR memgraph_dev; - --- Create with a GQL schema -CREATE GRAPH typed_graph { - NODE Person ({name STRING, age INT}), - EDGE KNOWS ()-[]->() -} ON CONNECTOR neo4j_prod; -``` - -### Modifying Graphs - -```gql --- Change access mode -ALTER GRAPH social SET READ ONLY; -ALTER GRAPH social SET READ WRITE; - --- Rebind to a different connector (e.g., failover) -ALTER GRAPH social SET CONNECTOR neo4j_staging; - --- Change the remote graph name -ALTER GRAPH social SET GRAPH production_db; - --- Attach or change a mapping -ALTER GRAPH knowledge SET MAPPING updated_mapping; -ALTER GRAPH knowledge REMOVE MAPPING; -``` - -### Removing Graphs - -```gql --- Remove from catalog only (remote graph is untouched) -UNADD GRAPH social; -UNADD GRAPH IF EXISTS social; - --- Remove from catalog AND drop on backend -DROP GRAPH analytics; -DROP GRAPH IF EXISTS analytics; -``` - -## Cross-Graph Query Rules - -1. **No pushed joins across backends**: Cross-graph joins always materialize both sides locally and hash-join. The engine never pushes join operations across different backends. - -2. **Property-based join keys**: Join keys must use node/edge properties. Internal IDs are backend-specific and not comparable across connectors. - -3. **Single-graph writes**: Mutations in multi-graph queries must target a single graph. The engine rejects mutations spanning multiple backends in one statement. - -4. **Compatible column types**: All branches of a composite query must produce result sets with the same number of columns, in the same order, with compatible types. - -## Complete Example - -Set up multiple backends and run cross-graph queries: - -```gql --- 1. Configure connectors -ADD CONNECTOR neo4j_prod TYPE neo4j URI 'bolt://neo4j:7687' USER 'neo4j' PASSWORD 'secret'; -ADD CONNECTOR pg_warehouse TYPE postgres URI 'postgresql://pg:5432/dw'; -ADD CONNECTOR ch_logs TYPE clickhouse URI 'http://clickhouse:8123'; - --- 2. Register graphs -ADD GRAPH social ON CONNECTOR neo4j_prod GRAPH neo4j; -ADD GRAPH warehouse ON CONNECTOR pg_warehouse MAPPING company_mapping READ ONLY; -ADD GRAPH events ON CONNECTOR ch_logs READ ONLY; - --- 3. Single-graph queries -USE social MATCH (p:Person) RETURN p.name LIMIT 5; -USE events MATCH (e:Event) RETURN e.type, COUNT(*) GROUP BY e.type; - --- 4. Multi-graph join -USE social -MATCH (p:Person)-[:WORKS_AT]->(c:Company) -USE warehouse -MATCH (wc:Company) -WHERE wc.name = c.name AND wc.revenue > 1000000 -RETURN p.name, c.name, wc.revenue; - --- 5. Composite across graphs -USE social MATCH (p:Person) RETURN p.email AS email -UNION -USE warehouse MATCH (e:Employee) RETURN e.email AS email; - --- 6. Cleanup -UNADD GRAPH social; -UNADD GRAPH warehouse; -UNADD GRAPH events; -``` diff --git a/pages/memgraph-zero/memgql/overview/_meta.ts b/pages/memgraph-zero/memgql/overview/_meta.ts new file mode 100644 index 000000000..602cbcd86 --- /dev/null +++ b/pages/memgraph-zero/memgql/overview/_meta.ts @@ -0,0 +1,5 @@ +export default { + "how-it-works": "How it works", + "use-cases": "Use Cases", + "editions": "Editions", +} diff --git a/pages/memgraph-zero/memgql/overview/editions.mdx b/pages/memgraph-zero/memgql/overview/editions.mdx new file mode 100644 index 000000000..c5c14c297 --- /dev/null +++ b/pages/memgraph-zero/memgql/overview/editions.mdx @@ -0,0 +1,33 @@ +--- +title: Editions +description: MemGQL Community and Enterprise comparison. +--- + +# Editions + +MemGQL ships in a free Community edition and a commercial +[Enterprise](https://memgraph.com/contact-us) edition. Every connector and the +full query surface are available in both — Enterprise lifts the runtime limits +on simultaneous connectors and connections. + +| Feature | Community | [Enterprise](https://memgraph.com/contact-us) | +|--------------------------------------------------------|-----------|-----------------------------------------------| +| GQL to Cypher translation | Yes | Yes | +| GQL to SQL translation | Yes | Yes | +| Bolt protocol | Yes | Yes | +| **Connectors** | | | +| [Memgraph](/memgraph-zero/memgql/connectors/memgraph) | Yes | Yes | +| [Neo4j](/memgraph-zero/memgql/connectors/neo4j) | Yes | Yes | +| [PostgreSQL](/memgraph-zero/memgql/connectors/postgres) | Yes | Yes | +| [DuckDB](/memgraph-zero/memgql/connectors/duckdb) | Yes | Yes | +| [Iceberg](/memgraph-zero/memgql/connectors/iceberg) | Yes | Yes | +| [ClickHouse](/memgraph-zero/memgql/connectors/clickhouse) | Yes | Yes | +| [MySQL](/memgraph-zero/memgql/connectors/mysql) | Yes | Yes | +| [Pinot](/memgraph-zero/memgql/connectors/pinot) | Yes | Yes | +| [Oracle](/memgraph-zero/memgql/connectors/oracle) | Yes | Yes | +| **Multi-Connection Mode** | Yes | Yes | +| Max connectors | 2 | Unlimited | +| Max simultaneous connections | 2 | Unlimited | +| **Agentic Capabilities** | | | +| MCP Server | Yes | Yes | +| Structured2Graph Agent to create mappings | Yes | Yes | diff --git a/pages/memgraph-zero/memgql/overview/how-it-works.mdx b/pages/memgraph-zero/memgql/overview/how-it-works.mdx new file mode 100644 index 000000000..0cd226473 --- /dev/null +++ b/pages/memgraph-zero/memgql/overview/how-it-works.mdx @@ -0,0 +1,79 @@ +--- +title: How it works +description: The MemGQL architecture — translation, mappings, connectors, and routing. +--- + +# How it works + +MemGQL is a federated query engine that speaks the [Bolt +protocol](https://en.wikipedia.org/wiki/Bolt_(network_protocol)) on port 7688. +Any Bolt-compatible client (mgconsole, a driver, Memgraph Lab) connects to it as +if it were a single graph database. MemGQL itself stores no data — it translates +each GQL query into a backend's native language, runs it on the backend, and +returns the result. + +``` +Bolt client ──GQL──▶ MemGQL ──┬──Cypher──▶ Memgraph / Neo4j + └──SQL─────▶ PostgreSQL / MySQL / Oracle / DuckDB / + ClickHouse / Iceberg / Pinot +``` + +## Translation + +What MemGQL emits depends on the connector: + +- **Cypher backends (Memgraph, Neo4j).** GQL is translated to Cypher (`-gql` + connectors), or forwarded unchanged in passthrough mode. +- **SQL backends.** GQL graph patterns are translated to SQL — node labels become + table scans and relationship patterns become `JOIN`s — in each backend's dialect. + +Because the same GQL runs everywhere, the surface of supported features differs by +backend. The [Connectors](/memgraph-zero/memgql/connectors) page has the exact +support matrix. + +## Mappings + +A graph database already knows what a node and a relationship are. A relational +backend does not — so MemGQL needs a **mapping** that says which table backs a +node label, which table backs a relationship type, and which columns are the join +keys. With a mapping in place, `MATCH (p:Person)-[:WORKS_AT]->(c:Company)` becomes +a SQL join across the `persons`, `works_at`, and `companies` tables. + +Mappings are required for every relational connector. See +[Mapping data to a graph](/memgraph-zero/memgql/guides/mapping) for the full +format. + +## Connectors, connections, and graphs + +Three concepts describe how MemGQL reaches a backend: + +- **Connector** — a registered backend definition (type + address + credentials +, + for relational backends, a mapping). +- **Connection** — a live, named session opened against a connector. +- **Graph** — a catalog entry that gives a connector (and optional remote + database + mapping) a friendly name you can `USE` in queries. + +In single-backend modes (`memgraph-gql`, `postgres`, …) the one backend is +configured via environment variables and these concepts stay implicit. In +[`multi` mode](/memgraph-zero/memgql/guides/querying-across-backends) you manage +them at runtime with statements like `ADD CONNECTOR`, `CONNECT`, and `ADD GRAPH`. + +## Routing + +When more than one backend is registered, MemGQL decides where each query runs: + +- **Automatic (schema-based) routing.** A query with no `USE` clause is routed by + matching the labels, relationship types, and properties it mentions against a + global schema index (built from relational mappings and from live introspection + of Cypher backends). If exactly one backend can satisfy the query, it routes + there. If two or more can, or none can, MemGQL returns an error naming the + candidates and how to disambiguate. +- **Explicit `USE`.** Naming the graph (`USE social MATCH …`) always wins and + bypasses inference — the escape hatch when a query is ambiguous or targets a + backend the index can't see. + +A single query can also span backends: MemGQL splits it at the right boundary, +runs each part on its backend, and joins the results in memory. See +[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends) +for how routing decides, when you still need `USE`, and how to make routing +reliable. diff --git a/pages/memgraph-zero/memgql/use-cases.mdx b/pages/memgraph-zero/memgql/overview/use-cases.mdx similarity index 72% rename from pages/memgraph-zero/memgql/use-cases.mdx rename to pages/memgraph-zero/memgql/overview/use-cases.mdx index 0d48576e8..2e4391bba 100644 --- a/pages/memgraph-zero/memgql/use-cases.mdx +++ b/pages/memgraph-zero/memgql/overview/use-cases.mdx @@ -1,42 +1,41 @@ --- title: Use Cases -description: Real-world patterns for Memgraph Zero and MemGQL. +description: Real-world patterns for MemGQL. --- # Use Cases -Memgraph Zero solves concrete problems that teams face when data is scattered -across systems, silos, and compliance boundaries. Each use case below shows a -real pattern, explains the architecture, and provides a working example you can -run yourself. +Each use case below shows a real pattern for querying data that's scattered +across systems, silos, and compliance boundaries — with the architecture and a +working example you can run yourself. -## [Federated GQL Across Heterogeneous Backends](/memgraph-zero/memgql/use-cases/federated-gql) +## [Federated GQL Across Heterogeneous Backends](/memgraph-zero/memgql/overview/use-cases/federated-gql) Run graph queries across non-graph stores like ClickHouse and PostgreSQL through a single GQL endpoint. Tables become nodes and edges through a mapping file; cross-store joins, pattern matching, and variable-length paths work without ETL or schema changes. -## [Public-Private Data / Data Sovereignty](/memgraph-zero/memgql/use-cases/public-private) +## [Public-Private Data / Data Sovereignty](/memgraph-zero/memgql/overview/use-cases/public-private) Keep sensitive data sovereign while querying it alongside public knowledge graphs. A GDPR-compliant PostgreSQL database stores private customer profiles, while a public Memgraph instance hosts the open product catalog. MemGQL joins both from a single query endpoint without ever moving the regulated data. -## [Horizontally Scalable Distributed Compute](/memgraph-zero/memgql/use-cases/distributed) +## [Horizontally Scalable Distributed Compute](/memgraph-zero/memgql/overview/use-cases/distributed) Spread graph computation across multiple nodes for workloads that exceed the capacity of a single instance. MemGQL can partition queries and materialize intermediate results across a cluster. -## [Enterprise Context Sharing](/memgraph-zero/memgql/use-cases/enterprise-context) +## [Enterprise Context Sharing](/memgraph-zero/memgql/overview/use-cases/enterprise-context) Share canonical context — org charts, product hierarchies, ontologies — across departments without forcing every team into the same database. Each team keeps its own data store; MemGQL provides a unified graph view. -## [Agentic Access](/memgraph-zero/memgql/use-cases/agentic) +## [Agentic Access](/memgraph-zero/memgql/overview/use-cases/agentic) Give AI agents a single semantic layer to discover and query any data in the organization. Agents use standard GQL to explore relationships across diff --git a/pages/memgraph-zero/memgql/use-cases/_meta.ts b/pages/memgraph-zero/memgql/overview/use-cases/_meta.ts similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/_meta.ts rename to pages/memgraph-zero/memgql/overview/use-cases/_meta.ts diff --git a/pages/memgraph-zero/memgql/use-cases/agentic.mdx b/pages/memgraph-zero/memgql/overview/use-cases/agentic.mdx similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/agentic.mdx rename to pages/memgraph-zero/memgql/overview/use-cases/agentic.mdx diff --git a/pages/memgraph-zero/memgql/use-cases/distributed.mdx b/pages/memgraph-zero/memgql/overview/use-cases/distributed.mdx similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/distributed.mdx rename to pages/memgraph-zero/memgql/overview/use-cases/distributed.mdx diff --git a/pages/memgraph-zero/memgql/use-cases/enterprise-context.mdx b/pages/memgraph-zero/memgql/overview/use-cases/enterprise-context.mdx similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/enterprise-context.mdx rename to pages/memgraph-zero/memgql/overview/use-cases/enterprise-context.mdx diff --git a/pages/memgraph-zero/memgql/use-cases/federated-gql.mdx b/pages/memgraph-zero/memgql/overview/use-cases/federated-gql.mdx similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/federated-gql.mdx rename to pages/memgraph-zero/memgql/overview/use-cases/federated-gql.mdx diff --git a/pages/memgraph-zero/memgql/use-cases/public-private.mdx b/pages/memgraph-zero/memgql/overview/use-cases/public-private.mdx similarity index 100% rename from pages/memgraph-zero/memgql/use-cases/public-private.mdx rename to pages/memgraph-zero/memgql/overview/use-cases/public-private.mdx diff --git a/pages/memgraph-zero/memgql/quick-start.mdx b/pages/memgraph-zero/memgql/quick-start.mdx deleted file mode 100644 index f816167c9..000000000 --- a/pages/memgraph-zero/memgql/quick-start.mdx +++ /dev/null @@ -1,298 +0,0 @@ ---- -title: Quick Start -description: Get started with MemGQL quickly. ---- - -# Quick Start - -MemGQL is a federated GQL (ISO/IEC 39075) query engine that translates GQL queries -into backend-native languages and executes them across graph databases. -Clients connect via the Bolt protocol (port 7688) using any Bolt-compatible driver. - -## Prerequisites - -- [Docker](https://docs.docker.com/get-started/get-docker/) -- [mgconsole](https://github.com/memgraph/mgconsole) (Memgraph Bolt CLI client) - -## Quick Start: Memgraph + MemGQL - -### 1. Create a Docker network - -```bash -docker network create memgql-net -``` - -### 2. Start Memgraph - -```bash -docker run -d --rm \ - --name memgraph-dev \ - --network memgql-net \ - -p 7687:7687 \ - memgraph/memgraph-mage:3.10.1 \ - --log-level=TRACE --also-log-to-stderr -``` - -### 3. Start MemGQL - -```bash -docker run --rm \ - --name memgql \ - --network memgql-net \ - --stop-timeout 2 \ - -p 7688:7688 \ - --env CONNECTOR_TYPE=memgraph-gql \ - --env MEMGRAPH_URI=memgraph-dev:7687 \ - --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ - memgraph/memgql:latest -``` - -### 4. Connect with mgconsole - -```bash -mgconsole --port 7688 -``` - -### 5. Seed some data - -```gql -INSERT - (lana:Developer {name: "Lana", level: "senior", yoe: 12}), - (marco:Developer {name: "Marco", level: "mid", yoe: 5}), - (priya:Developer {name: "Priya", level: "senior", yoe: 9}), - (rs:Language {name: "Rust", releaseYear: 2010}), - (go:Language {name: "Go", releaseYear: 2009}), - (ts:Language {name: "TypeScript", releaseYear: 2012}), - (acme:Startup {name: "Acme Labs", funding: 4200000}), - (nova:Startup {name: "Nova AI", funding: 18500000}), - (lana)-[:WRITES {since: 2018}]->(rs), - (lana)-[:WRITES {since: 2021}]->(go), - (marco)-[:WRITES {since: 2022}]->(ts), - (priya)-[:WRITES {since: 2019}]->(rs), - (priya)-[:WRITES {since: 2020}]->(ts), - (lana)-[:MENTORS]->(marco), - (priya)-[:MENTORS]->(marco), - (lana)-[:EMPLOYED_AT {role: "CTO"}]->(acme), - (marco)-[:EMPLOYED_AT {role: "Backend Engineer"}]->(nova), - (priya)-[:EMPLOYED_AT {role: "Tech Lead"}]->(nova); -``` - -### 6. Run GQL queries - -Count all nodes in the graph: - -```gql -MATCH () RETURN count(*); -``` - -Return developers and their experience: - -```gql -MATCH (d:Developer) RETURN d.name, d.yoe; -``` - -Filter with WHERE inside the pattern (GQL syntax): - -```gql -MATCH (d:Developer WHERE d.yoe > 8) RETURN d.name, d.level; -``` - -Label expression with IS keyword: - -```gql -MATCH (s IS Startup) RETURN s.name, s.funding; -``` - -OR label expression — match multiple labels at once: - -```gql -MATCH (n:Language|Startup) RETURN n; -``` - -Edge pattern with direction and type: - -```gql -MATCH (:Developer)-[w:WRITES]->(lang:Language) RETURN lang.name, w.since; -``` - -Edge with WHERE clause: - -```gql -MATCH (:Developer)-[w:WRITES WHERE w.since < 2020]->(lang:Language) RETURN lang.name; -``` - -Path variable binding: - -```gql -MATCH p = (:Developer)-[:MENTORS]->(:Developer) RETURN p; -``` - -Two-hop traversal — who mentors someone employed at a startup: - -```gql -MATCH (senior:Developer)-[:MENTORS]->(junior:Developer)-[:EMPLOYED_AT]->(s:Startup) -RETURN senior.name, junior.name, s.name; -``` - -Variable-length path (quantified path pattern): - -```gql -MATCH (d:Developer {name: "Lana"})-[:MENTORS]->{1,3}(mentee:Developer) RETURN mentee.name; -``` - -## Environment Variables - -See [Reference](/memgraph-zero/memgql/reference) for the full list of -environment variables and connector-specific settings. - - -## Mapping File - -Relational connectors (PostgreSQL, MySQL, Oracle, DuckDB, ClickHouse, Iceberg, and -Apache Pinot) and multi-connection mode require a JSON mapping file that defines -how graph patterns map to relational tables. Node labels map to tables and edge types map to association tables, -allowing GQL patterns like `MATCH (p:Person)-[:WORKS_AT]->(c:Company)` to be -translated into SQL JOINs. - -Create a mapping file: - -```bash -cat > mapping.json << 'EOF' -{ - "nodes": [ - { - "label": "Person", - "table": "persons", - "id_column": "id", - "properties": { "name": "name", "age": "age" } - }, - { - "label": "Company", - "table": "companies", - "id_column": "id", - "properties": { "name": "name" } - } - ], - "edges": [ - { - "rel_type": "KNOWS", - "table": "knows", - "id_column": "id", - "source_column": "from_id", - "target_column": "to_id", - "source_label": "Person", - "target_label": "Person" - }, - { - "rel_type": "WORKS_AT", - "table": "works_at", - "id_column": "id", - "source_column": "person_id", - "target_column": "company_id", - "source_label": "Person", - "target_label": "Company" - } - ] -} -EOF -``` - -Without `MAPPING_FILE`, a default Person/Company mapping (shown above) is used. - -## Multi-Connection Mode - -Multi-connection mode (`CONNECTOR_TYPE=multi`) lets you manage multiple backend -connectors and connections at runtime using MemGQL statements. You can add -connectors, establish connections, and route queries to specific backends — all -from within the same Bolt session. - -### 1. Start MemGQL in multi mode - -```bash -docker run --rm \ - --name memgql \ - --network memgql-net \ - --stop-timeout 2 \ - -p 7688:7688 \ - --env CONNECTOR_TYPE=multi \ - --env BOLT_LISTEN_ADDR=0.0.0.0:7688 \ - -v ./mapping.json:/data/mapping.json \ - memgraph/memgql:latest -``` - -### 2. Connect and manage backends - -```bash -mgconsole --port 7688 -``` - -Add connectors and establish connections: - -```gql -ADD CONNECTOR mg TYPE memgraph URI 'memgraph-dev:7687' GRAPH memgraph; -CONNECT mg AS mg_conn; - -ADD CONNECTOR neo TYPE neo4j URI 'neo4j-dev:7687' GRAPH neo4j; -CONNECT neo AS neo_conn; -``` - -### 3. Route queries to specific connections - -```gql -USE CONNECTION mg_conn MATCH (n) RETURN n.name LIMIT 5; -USE CONNECTION neo_conn MATCH (n) RETURN n.name LIMIT 5; -``` - -### 4. Introspection - -```gql -SHOW CONNECTORS; -SHOW CONNECTIONS; -SHOW MAPPINGS; -PING mg_conn; -``` - -### 5. Adding relational backends - -Relational connectors (PostgreSQL, MySQL, Oracle, DuckDB, ClickHouse, Iceberg, and -Apache Pinot) require a mapping that defines how graph patterns map to tables: - -```gql -ADD MAPPING social FROM '/data/mapping.json'; -ADD CONNECTOR pg TYPE postgres USER 'postgres' PASSWORD 'postgres' DATABASE 'postgres' MAPPING social; -CONNECT pg AS pg_conn; -USE CONNECTION pg_conn MATCH (n:Person) RETURN n.name LIMIT 5; -``` - -Pinot can also run as a single backend with the alias requested by deployment -environments that use connection naming: - -```bash -CONNECTION_TYPE=pinot PINOT_URL=http://localhost:8099 cargo run --bin bolt_server -``` - -### 6. Cleanup - -```gql -DISCONNECT pg_conn; -DROP CONNECTOR pg; -DROP MAPPING social; -``` - -### MemGQL Statements Reference - -| Statement | Description | -|----------------------------------------------------|---------------------------------------| -| `ADD MAPPING FROM ''` | Load a graph mapping from a JSON file | -| `DROP MAPPING ` | Remove a mapping | -| `ADD CONNECTOR TYPE [options...]` | Register a backend connector | -| `DROP CONNECTOR ` | Remove a connector | -| `CONNECT AS [DEFAULT]` | Establish a named connection | -| `DISCONNECT ` | Close a connection | -| `PING ` | Test a connection is alive | -| `USE CONNECTION ` | Route a query to a specific connection| -| `SET DEFAULT CONNECTOR ` | Set session default connector | -| `SET DEFAULT CONNECTION ` | Set session default connection | -| `SHOW CONNECTORS` | List registered connectors | -| `SHOW CONNECTIONS` | List active connections | -| `SHOW MAPPINGS` | List loaded mappings | diff --git a/pages/memgraph-zero/memgql/reference.mdx b/pages/memgraph-zero/memgql/reference.mdx index 6529a8818..cd15083d1 100644 --- a/pages/memgraph-zero/memgql/reference.mdx +++ b/pages/memgraph-zero/memgql/reference.mdx @@ -1,335 +1,42 @@ --- title: Reference -description: All the details about syntax and various configs +description: GQL feature support, statements, configuration, and licensing. --- -## Supported GQL Query Features - -What works today, split by backend category. "Cypher backends" means -Memgraph and Neo4j (translation is largely passthrough); "SQL backends" -means PostgreSQL, MySQL and DuckDB. - -ClickHouse, Apache Iceberg, and Apache Pinot are also supported as -connectors but with a narrower verified surface. See each connector's page for the exact list of features each one -supports. - -| Feature | Cypher backends | SQL backends | -|--------------------------------------------------------------------|-----------------|--------------| -| `MATCH` / `WHERE` / `RETURN` | ✓ | ✓ | -| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ | ✓ | -| Multiple `MATCH` clauses in one query | ✓ | ✓ | -| `OPTIONAL MATCH` (keep left side when no match found) | ✓ | ✓ | -| `WITH` clause (chain query steps) | ✓ | ✓ | -| `WITH DISTINCT` / `WITH … ORDER BY … LIMIT N` | ✓ | ✓ | -| Multiple chained `WITH` steps in one query | ✓ | ✓ | -| Pass a whole node through `WITH n` to a later step | ✓ | ✓ | -| `MATCH (n)-[r:R]->(m)` typed edge expansion | ✓ | ✓ | -| Untyped edge `()-[]->(b)` (union over types) | ✓ | ✗ | -| `UNION` / `UNION ALL` / `UNION DISTINCT` | ✓ | ✓ | -| `INTERSECT` / `EXCEPT` | ✗ | ✗ | -| Quantified path `(){m,n}` — bounded | ✓ | ✓ | -| Quantified path `(){m,}` — unbounded | ✓ | ✗ | -| Shortest-path (`ALL SHORTEST` / `ANY SHORTEST` / `SHORTEST k`) | ✓ | ✗ | ✗ | -| Map projections `RETURN n {.id, .title}` | ✓ | ✓ | -| `IN` list membership `WHERE x IN […]` | ✓ | ✓ | -| `STARTS WITH` / `ENDS WITH` / `CONTAINS` | ✓ | ✓ | -| `collect()` / `collect_list()` (aggregate) | ✓ | ✓ | -| `count`, `sum`, `avg`, `min`, `max` | ✓ | ✓ | -| `COUNT(DISTINCT …)` | ✓ | ✓ | -| Arithmetic `+ - * / %` | ✓ | ✓ | -| `CASE WHEN … THEN … ELSE … END` | ✓ | ✓ | -| `COALESCE`, `NULLIF` | ✓ | ✓ | -| Temporals (`date`, `datetime`, `localTime`, …) | ✓ | ✗ | -| `INSERT (a {…}) RETURN a.x` | ✓ | ✓ | -| `DELETE` | ✓ | ✓ | -| `DETACH DELETE` | ✓ | ✗ | -| `SET` (property update) | ✓ | ✗ | -| `REMOVE` (property delete) | ✓ | ✗ | - -### Known limitations - -- **Unbounded variable-length paths on SQL backends** (`()-[*]->()`) - return an actionable error. -- **Untyped edge traversal on SQL backends** (`MATCH ()-[]->(b)` with - no rel-type) returns an actionable error pointing users at declaring - the edge type or running on a Cypher backend. The form is still - accepted natively on Cypher backends. -- **`FOR x IN [...]` (UNWIND-style) on SQL backends** returns an - actionable error pointing users at running the query on a Cypher - backend. The form is still accepted natively on Cypher backends. -- **Path variables on variable-length patterns** — - `MATCH p = (a){1,3}(b) RETURN p` is not yet supported on SQL backends. - Drop the `p =` binding (or query a Cypher backend) and `RETURN` the - individual nodes / edges instead. -- **`RETURN n` on SQL backends returns the node's column values** rather - than a single structured node object. For a structured result, use a - map projection: `RETURN n {.id, .name} AS info`. - -## Graph Management Query Syntax - -``` -ADD GRAPH ON CONNECTOR - [GRAPH ] - [MAPPING ] - [READ ONLY]; - -CREATE GRAPH - [{ } | ANY] - ON CONNECTOR ; - -UNADD GRAPH [IF EXISTS] ; -DROP GRAPH [IF EXISTS] ; - -ALTER GRAPH SET READ ONLY; -ALTER GRAPH SET READ WRITE; -ALTER GRAPH SET CONNECTOR ; -ALTER GRAPH SET GRAPH ; -ALTER GRAPH SET MAPPING ; -ALTER GRAPH REMOVE MAPPING; -``` - -``` --- Single graph -USE ; - --- Composite -USE -UNION | UNION ALL | INTERSECT | INTERSECT ALL | EXCEPT | EXCEPT ALL -USE ; -``` - -## Configuration Reference - -### General - -| Variable | Default | Description | -|--------------------|---------------------|--------------------------------------| -| `CONNECTOR_TYPE` | `memgraph` | Connector to use (see table below) | -| `CONNECTION_TYPE` | _(none)_ | Alias for `CONNECTOR_TYPE` | -| `BOLT_LISTEN_ADDR` | `127.0.0.1:7688` | Address the Bolt server binds to | - -### Logging - -MemGQL writes log lines to the console (stdout/stderr) and, in parallel, to a -log file. Both destinations are configured via CLI flags on the Bolt server -binary. - -#### CLI Flags - -| Flag | Default | Description | -|------------------------|--------------------|--------------------------------------------------------------| -| `--log-level=` | `info` | Console logging verbosity (see levels below) | -| `--log-file=` | `bolt_server.log` | File to mirror all log output to (always written, regardless of `--log-level`) | - -#### Log Levels - -| Level | Console output | -|----------------------|---------------------------------------------------------------------------------| -| `info` | Full logging: connections, incoming queries, transpiled output, results, state changes | -| `info-queries-only` | Only the incoming GQL query and its transpiled output (Cypher / SQL) | - -`info` is the most verbose level today. There is no `debug` or `trace`. The -`RUST_LOG` environment variable is not consulted. - -The log file always receives every log line — including queries, errors, and -state changes — independent of the console `--log-level`. To silence the -console while keeping a full file record, use `--log-level=info-queries-only` -and tail the log file separately. - -### Enterprise License - -| Variable | Default | Description | -|-------------------------------|---------|------------------------------------------| -| `MEMGQL_ENTERPRISE_LICENSE` | _(none)_ | License key (`mglk-...`) | -| `MEMGQL_ORGANIZATION_NAME` | _(none)_ | Organization name to verify against license | - -When set, the license is decoded and verified against the organization name at -startup. A valid enterprise license removes connector and connection limits. -Without a license, community mode allows up to 2 connectors and 2 simultaneous -connections. - -### Connector Types - -| Connector | Translation | Backend | -|----------------|--------------------|----------------------------------| -| `memgraph` | None (passthrough) | Memgraph | -| `memgraph-gql` | GQL -> Cypher | Memgraph | -| `neo4j` | None (passthrough) | Neo4j | -| `neo4j-gql` | GQL -> Cypher | Neo4j | -| `postgres` | GQL -> SQL | PostgreSQL | -| `mysql` | GQL -> SQL | MySQL 8.0+ | -| `oracle` | GQL -> SQL | Oracle 19c+ (incl. Free 23ai) | -| `duckdb` | GQL -> SQL | DuckDB (embedded) | -| `clickhouse` | GQL -> SQL | ClickHouse | -| `iceberg` | GQL -> SQL | Iceberg via Trino | -| `pinot` | GQL -> SQL | Apache Pinot | -| `multi` | Per-connector | Multiple backends simultaneously | - - -#### Memgraph (`memgraph`, `memgraph-gql`) - -| Variable | Default | Description | -|-----------------|------------------|----------------| -| `MEMGRAPH_URI` | `127.0.0.1:7687` | Connection URI | -| `MEMGRAPH_USER` | `user` | Username | -| `MEMGRAPH_PASS` | `pass` | Password | -| `MEMGRAPH_DB` | `memgraph` | Database name | - -#### Neo4j (`neo4j`, `neo4j-gql`) - -| Variable | Default | Description | -|--------------|------------------|----------------| -| `NEO4J_URI` | `127.0.0.1:7687` | Connection URI | -| `NEO4J_USER` | `neo4j` | Username | -| `NEO4J_PASS` | `password` | Password | -| `NEO4J_DB` | `neo4j` | Database name | - -#### PostgreSQL (`postgres`) - -| Variable | Default | Description | -|----------------|-----------------------------------------------------------------|---------------------------| -| `POSTGRES_URL` | `host=localhost user=postgres password=postgres dbname=postgres` | libpq connection string | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -#### MySQL (`mysql`) - -| Variable | Default | Description | -|----------------|-----------------------------------------------|------------------------------------------| -| `MYSQL_URL` | `mysql://root:mysql@localhost:3306/test` | MySQL connection URL (`mysql://user:pass@host:port/database`) | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -#### Oracle (`oracle`) - -| Variable | Default | Description | -|-----------------|----------------------------------------------------------|------------------------------------------| -| `ORACLE_URL` | `oracle://system:oracle@localhost:1521/FREEPDB1` | Easy Connect URL (`oracle://user:pass@host:port/service_name`). The default targets [Oracle Database Free 23ai](https://www.oracle.com/database/free/) (service `FREEPDB1`). | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file (same format as Postgres) | - -The Oracle connector uses [oracle-rs](https://crates.io/crates/oracle-rs), a -pure-Rust implementation of Oracle's TNS wire protocol, pooled via -[deadpool-oracle](https://crates.io/crates/deadpool-oracle). No OCI / ODPI-C -/ Instant Client is required at build or runtime — the bundled Docker image -ships only the bolt server binary plus TLS roots, and local builds work on -macOS, Linux, and Windows without any extra system packages. - -#### DuckDB (`duckdb`) - -| Variable | Default | Description | -|----------------|---------------------------------|---------------------------| -| `DUCKDB_PATH` | `:memory:` | Path to DuckDB file | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -#### ClickHouse (`clickhouse`) - -| Variable | Default | Description | -|-------------------|---------------------------|---------------------------| -| `CLICKHOUSE_URL` | `http://localhost:8123` | ClickHouse HTTP API URL | -| `CLICKHOUSE_USER` | `default` | ClickHouse user | -| `CLICKHOUSE_PASS` | _(none)_ | ClickHouse password | -| `CLICKHOUSE_DB` | `default` | ClickHouse database | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -#### Apache Pinot (`pinot`) - -| Variable | Default | Description | -|-----------------------|----------------------------|--------------------------------------------------| -| `PINOT_URL` | `http://localhost:8099` | Pinot broker base URL or full SQL endpoint | -| `PINOT_QUERY_OPTIONS` | `useMultistageEngine=true` | Query options sent with broker SQL requests | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -#### Iceberg (`iceberg`) - -| Variable | Default | Description | -|-----------------|-------------------------|---------------------------| -| `TRINO_URL` | `http://localhost:8080` | Trino REST API URL | -| `TRINO_USER` | `trino` | Trino user | -| `TRINO_CATALOG` | `iceberg` | Trino catalog | -| `TRINO_SCHEMA` | `default` | Trino schema | -| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | - -## Mapping Schema - -The graph mapping file is a JSON document with two top-level arrays: -`nodes` and `edges`. MemGQL loads it either from the path in `MAPPING_FILE` -at startup or via the `ADD MAPPING FROM ''` statement at -runtime — both paths apply the same validation. A mapping with any -required field missing is rejected before the server begins serving -queries against it. - -```json -{ - "nodes": [ /* NodeMapping objects */ ], - "edges": [ /* EdgeMapping objects */ ] -} -``` - -### Node mapping fields - -| Field | Type | Required | Description | -|--------------|-------------------------|----------|-------------| -| `label` | string | yes | GQL node label (e.g. `"Person"`). Looked up case-insensitively. | -| `table` | string | yes | Backend table or view name backing this label. | -| `id_column` | string | yes | Primary key column. Surfaces as GQL `id(n)` and is used to join across edges. | -| `properties` | object (string→string) | no | Map from GQL property name → backend column name. Properties not listed here pass through with the same name (`p.name` → column `name`). | - -Connector-specific fields: - -- **Iceberg** also accepts `catalog` and `schema_name` to fully qualify the - table reference (defaults: `"iceberg"`, `"default"`). -- **ClickHouse** also accepts `database` (default: `"default"`). - -### Edge mapping fields - -| Field | Type | Required | Description | -|------------------|-------------------------|----------|-------------| -| `rel_type` | string | yes | GQL relationship type (e.g. `"KNOWS"`). Looked up case-insensitively. | -| `table` | string | yes | Junction or association table backing this edge type. | -| `id_column` | string | yes | Per-edge primary key. **Required since v0.6.** Carried through the recursive CTE's visited-edge set to enforce trail semantics on variable-length traversal. | -| `source_column` | string | yes | FK column pointing to the source node's `id_column`. | -| `target_column` | string | yes | FK column pointing to the target node's `id_column`. | -| `source_label` | string | yes | Label of the source node (must match a `label` declared in `nodes`). | -| `target_label` | string | yes | Label of the target node. | -| `properties` | object (string→string) | no | Map from GQL property name → column name on the edge table. | - -Connector-specific fields are the same as for nodes (`catalog` / `schema_name` -for Iceberg; `database` for ClickHouse). - -### Example - -```json -{ - "nodes": [ - { - "label": "Person", - "table": "persons", - "id_column": "id", - "properties": { "name": "full_name", "age": "age" } - }, - { - "label": "Company", - "table": "companies", - "id_column": "id" - } - ], - "edges": [ - { - "rel_type": "KNOWS", - "table": "knows", - "id_column": "id", - "source_column": "from_id", - "target_column": "to_id", - "source_label": "Person", - "target_label": "Person" - }, - { - "rel_type": "WORKS_AT", - "table": "works_at", - "id_column": "id", - "source_column": "person_id", - "target_column": "company_id", - "source_label": "Person", - "target_label": "Company" - } - ] -} -``` +# Reference + +- **GQL feature support** — what works, by backend (below). +- **[Statements & catalog](/memgraph-zero/memgql/reference/statements)** — management statements and catalog grammar. +- **[Configuration & env vars](/memgraph-zero/memgql/reference/configuration)** — environment variables and logging. +- **[Licensing](/memgraph-zero/memgql/reference/licensing)** — terms of use. +- **[Changelog](/memgraph-zero/memgql/reference/changelog)** — release notes. + +## GQL feature support + +The exact, per-backend support table lives on the +**[Connectors](/memgraph-zero/memgql/connectors#feature-support)** page — it's the +single source of truth, grouped by backend tier (Graph / Relational / Analytical) with +a `✓`/`✗`/read-only legend. + +At a glance: **Cypher backends** (Memgraph, Neo4j) support the full surface. **SQL +backends** (PostgreSQL, MySQL, Oracle, DuckDB) support reads, writes, bounded paths, +and aggregations, but not untyped edges, unbounded/shortest paths, temporals, `SET` / +`REMOVE`, or `DETACH DELETE`. **Analytical backends** (ClickHouse, Iceberg, Pinot) are +read-oriented with a narrower verified surface; Pinot is read-only. + +### Known limitations on SQL backends + +- **Unbounded variable-length paths** (`()-[*]->()`) return an actionable error — + bound the depth (`{1,5}`) or use a Cypher backend. +- **Untyped edge traversal** (`MATCH ()-[]->(b)` with no rel-type) returns an + actionable error pointing at declaring the edge type or using a Cypher backend. + The form is accepted natively on Cypher backends. +- **`FOR x IN [...]` (UNWIND-style)** returns an actionable error pointing at a Cypher + backend, which handles the syntax natively. +- **Path variables on variable-length patterns** — `MATCH p = (a){1,3}(b) RETURN p` + is not yet supported. Drop the `p =` binding (or use a Cypher backend) and `RETURN` + the individual nodes / edges instead. + +For the mapping file format see [Mapping data to a +graph](/memgraph-zero/memgql/guides/mapping); for routing across backends see +[Querying across backends](/memgraph-zero/memgql/guides/querying-across-backends). diff --git a/pages/memgraph-zero/memgql/reference/_meta.ts b/pages/memgraph-zero/memgql/reference/_meta.ts new file mode 100644 index 000000000..eea15a49d --- /dev/null +++ b/pages/memgraph-zero/memgql/reference/_meta.ts @@ -0,0 +1,6 @@ +export default { + "statements": "Statements & catalog", + "configuration": "Configuration & env vars", + "licensing": "Licensing", + "changelog": "Changelog", +} diff --git a/pages/memgraph-zero/memgql/changelog.mdx b/pages/memgraph-zero/memgql/reference/changelog.mdx similarity index 78% rename from pages/memgraph-zero/memgql/changelog.mdx rename to pages/memgraph-zero/memgql/reference/changelog.mdx index 60dba10ff..cccd79564 100644 --- a/pages/memgraph-zero/memgql/changelog.mdx +++ b/pages/memgraph-zero/memgql/reference/changelog.mdx @@ -5,6 +5,53 @@ description: MemGQL release notes # MemGQL Changelog +## MemGQL v0.7.0 - TBD + +### ✨ New features & Improvements + +- **USE-free schema-based routing.** Queries with no `USE` clause are routed to the + right backend by matching their labels, relationship types, and properties against a + global schema index (built from relational mappings and live Cypher introspection). + Exactly one candidate routes; zero or several hard-error and name the fix. USE-free + federated joins and `UNION`s route per part. Explicit `USE` always wins and bypasses + inference. See [Querying across + backends](/memgraph-zero/memgql/guides/querying-across-backends). +- **`SHOW SCHEMA` / `REFRESH SCHEMA`.** `SHOW SCHEMA [FOR ]` prints the schema + index per source (labels, properties, relationship types) — the discoverability + surface for agents and what routing errors point at. `REFRESH SCHEMA` re-introspects + live Cypher connections. +- **Typed projections on every SQL backend.** `RETURN p` now returns a + structured Bolt **Node** and `RETURN r` a typed Bolt **Relationship** on + every SQL connector (PostgreSQL, MySQL, DuckDB, ClickHouse, Iceberg, Pinot, + Oracle) — previously SQL backends returned the underlying column values and a + map projection (`RETURN p {.id, .name}`) was required. Nodes carry their + label and mapped properties; relationships carry their type and mapped + properties. Mixing scalar and whole-element projections in one `RETURN` + (`RETURN p.name, p`) works too. +- **Connection-less queries (liveness check).** `RETURN 1`, `RETURN 1 + 2 AS x` + and `WITH 1 AS x RETURN x` now evaluate locally with no connector configured + and no backend reachable — useful as a Bolt-level health probe. +- **`ORDER BY` by `RETURN` alias in cross-backend queries.** A sort key can + reference a projected alias (`RETURN fact.tx_count AS tx_count … ORDER BY + tx_count`), including when the alias is nested inside an arithmetic + expression (`ORDER BY tx_count + 1`). The post-join sort rewrites the alias + back to its underlying expression. +- **Delimited (quoted) identifiers** in GQL queries now parse. + +### ⚠️ Behavior changes + +- **Identifiers are now matched case-sensitively.** A query that says + `MATCH (:person)` no longer matches a mapping that declares `Person` — routing, + translation, and the backends now agree on exact matching. Spell labels, relationship + types, and property names in your [mapping](/memgraph-zero/memgql/guides/mapping) + exactly as you write them in queries. + +### 🐞 Bug fixes + +- **PostgreSQL `NUMERIC` columns** now deserialize correctly — whole and + fractional values arrive at the Bolt driver as Float and `NULL` is + preserved. Previously `NUMERIC`-typed columns were unsupported. + ## MemGQL v0.6.1 - May 31st, 2026 ### ✨ New features & Improvements @@ -62,7 +109,7 @@ description: MemGQL release notes whether the mapping is supplied via `MAPPING_FILE` at startup or via `ADD MAPPING` at runtime. Update existing mappings by adding the edge table's primary key column to every edge — see the - [quick-start](/memgraph-zero/memgql/quick-start) and connector examples + [quick-start](/memgraph-zero/memgql/get-started/quick-start) and connector examples for the new shape. - **Untyped edge traversal `()-[]->(b)` now errors on SQL backends.** Previously this expanded into a `UNION` over candidate rel-type mappings diff --git a/pages/memgraph-zero/memgql/reference/configuration.mdx b/pages/memgraph-zero/memgql/reference/configuration.mdx new file mode 100644 index 000000000..e6afaceb8 --- /dev/null +++ b/pages/memgraph-zero/memgql/reference/configuration.mdx @@ -0,0 +1,160 @@ +--- +title: Configuration & env vars +description: Environment variables, connector settings, and logging configuration. +--- + +# Configuration & environment variables + +## General + +| Variable | Default | Description | +|--------------------|---------------------|--------------------------------------| +| `CONNECTOR_TYPE` | `memgraph` | Connector to use (see table below) | +| `CONNECTION_TYPE` | _(none)_ | Alias for `CONNECTOR_TYPE` | +| `BOLT_LISTEN_ADDR` | `127.0.0.1:7688` | Address the Bolt server binds to | + +The default `memgraph` connector is **passthrough** — it forwards queries to Memgraph +unchanged as Cypher. To translate GQL into Cypher, use `memgraph-gql` (or `neo4j-gql`); +GQL-only syntax such as `INSERT (a {…})` requires a `-gql` or SQL connector. + +## Logging + +MemGQL writes log lines to the console (stdout/stderr) and, in parallel, to a +log file. Both destinations are configured via CLI flags on the Bolt server +binary. + +### CLI flags + +| Flag | Default | Description | +|------------------------|--------------------|--------------------------------------------------------------| +| `--log-level=` | `info` | Console logging verbosity (see levels below) | +| `--log-file=` | `bolt_server.log` | File to mirror all log output to (always written, regardless of `--log-level`) | + +### Log levels + +| Level | Console output | +|----------------------|---------------------------------------------------------------------------------| +| `info` | Full logging: connections, incoming queries, transpiled output, results, state changes | +| `info-queries-only` | Only the incoming GQL query and its transpiled output (Cypher / SQL) | + +`info` is the most verbose level today. There is no `debug` or `trace`. The +`RUST_LOG` environment variable is not consulted. + +The log file always receives every log line — including queries, errors, and +state changes — independent of the console `--log-level`. To silence the +console while keeping a full file record, use `--log-level=info-queries-only` +and tail the log file separately. + +## Enterprise license + +| Variable | Default | Description | +|-------------------------------|---------|------------------------------------------| +| `MEMGQL_ENTERPRISE_LICENSE` | _(none)_ | License key (`mglk-...`) | +| `MEMGQL_ORGANIZATION_NAME` | _(none)_ | Organization name to verify against license | + +When set, the license is decoded and verified against the organization name at +startup. A valid enterprise license removes connector and connection limits. +Without a license, community mode allows up to 2 connectors and 2 simultaneous +connections. + +## Connector types + +| Connector | Translation | Backend | +|----------------|--------------------|----------------------------------| +| `memgraph` | None (passthrough) | Memgraph | +| `memgraph-gql` | GQL -> Cypher | Memgraph | +| `neo4j` | None (passthrough) | Neo4j | +| `neo4j-gql` | GQL -> Cypher | Neo4j | +| `postgres` | GQL -> SQL | PostgreSQL | +| `mysql` | GQL -> SQL | MySQL 8.0+ | +| `oracle` | GQL -> SQL | Oracle 19c+ (incl. Free 23ai) | +| `duckdb` | GQL -> SQL | DuckDB (embedded) | +| `clickhouse` | GQL -> SQL | ClickHouse | +| `iceberg` | GQL -> SQL | Iceberg via Trino | +| `pinot` | GQL -> SQL | Apache Pinot | +| `multi` | Per-connector | Multiple backends simultaneously | + + +#### Memgraph (`memgraph`, `memgraph-gql`) + +| Variable | Default | Description | +|-----------------|------------------|----------------| +| `MEMGRAPH_URI` | `127.0.0.1:7687` | Connection URI | +| `MEMGRAPH_USER` | `user` | Username | +| `MEMGRAPH_PASS` | `pass` | Password | +| `MEMGRAPH_DB` | `memgraph` | Database name | + +#### Neo4j (`neo4j`, `neo4j-gql`) + +| Variable | Default | Description | +|--------------|------------------|----------------| +| `NEO4J_URI` | `127.0.0.1:7687` | Connection URI | +| `NEO4J_USER` | `neo4j` | Username | +| `NEO4J_PASS` | `password` | Password | +| `NEO4J_DB` | `neo4j` | Database name | + +#### PostgreSQL (`postgres`) + +| Variable | Default | Description | +|----------------|-----------------------------------------------------------------|---------------------------| +| `POSTGRES_URL` | `host=localhost user=postgres password=postgres dbname=postgres` | libpq connection string | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +#### MySQL (`mysql`) + +| Variable | Default | Description | +|----------------|-----------------------------------------------|------------------------------------------| +| `MYSQL_URL` | `mysql://root:mysql@localhost:3306/test` | MySQL connection URL (`mysql://user:pass@host:port/database`) | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +#### Oracle (`oracle`) + +| Variable | Default | Description | +|-----------------|----------------------------------------------------------|------------------------------------------| +| `ORACLE_URL` | `oracle://system:oracle@localhost:1521/FREEPDB1` | Easy Connect URL (`oracle://user:pass@host:port/service_name`). The default targets [Oracle Database Free 23ai](https://www.oracle.com/database/free/) (service `FREEPDB1`). | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file (same format as Postgres) | + +The Oracle connector uses [oracle-rs](https://crates.io/crates/oracle-rs), a +pure-Rust implementation of Oracle's TNS wire protocol, pooled via +[deadpool-oracle](https://crates.io/crates/deadpool-oracle). No OCI / ODPI-C +/ Instant Client is required at build or runtime — the bundled Docker image +ships only the bolt server binary plus TLS roots, and local builds work on +macOS, Linux, and Windows without any extra system packages. + +#### DuckDB (`duckdb`) + +| Variable | Default | Description | +|----------------|---------------------------------|---------------------------| +| `DUCKDB_PATH` | `:memory:` | Path to DuckDB file | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +#### ClickHouse (`clickhouse`) + +| Variable | Default | Description | +|-------------------|---------------------------|---------------------------| +| `CLICKHOUSE_URL` | `http://localhost:8123` | ClickHouse HTTP API URL | +| `CLICKHOUSE_USER` | `default` | ClickHouse user | +| `CLICKHOUSE_PASS` | _(none)_ | ClickHouse password | +| `CLICKHOUSE_DB` | `default` | ClickHouse database | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +#### Apache Pinot (`pinot`) + +| Variable | Default | Description | +|-----------------------|----------------------------|--------------------------------------------------| +| `PINOT_URL` | `http://localhost:8099` | Pinot broker base URL or full SQL endpoint | +| `PINOT_QUERY_OPTIONS` | `useMultistageEngine=true` | Query options sent with broker SQL requests | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +#### Iceberg (`iceberg`) + +| Variable | Default | Description | +|-----------------|-------------------------|---------------------------| +| `TRINO_URL` | `http://localhost:8080` | Trino REST API URL | +| `TRINO_USER` | `trino` | Trino user | +| `TRINO_CATALOG` | `iceberg` | Trino catalog | +| `TRINO_SCHEMA` | `default` | Trino schema | +| `MAPPING_FILE` | _(none, uses built-in default)_ | Path to JSON mapping file | + +For the mapping file format, see [Mapping data to a +graph](/memgraph-zero/memgql/guides/mapping). diff --git a/pages/memgraph-zero/memgql/licensing.mdx b/pages/memgraph-zero/memgql/reference/licensing.mdx similarity index 100% rename from pages/memgraph-zero/memgql/licensing.mdx rename to pages/memgraph-zero/memgql/reference/licensing.mdx diff --git a/pages/memgraph-zero/memgql/reference/statements.mdx b/pages/memgraph-zero/memgql/reference/statements.mdx new file mode 100644 index 000000000..8c9bc10b9 --- /dev/null +++ b/pages/memgraph-zero/memgql/reference/statements.mdx @@ -0,0 +1,86 @@ +--- +title: Statements & catalog +description: MemGQL management statements, graph-catalog grammar, and schema introspection. +--- + +# Statements & catalog + +These statements are available in [`multi` +mode](/memgraph-zero/memgql/guides/querying-across-backends). Single-backend modes +connect to one backend via environment variables and don't expose the catalog. + +## Connectors, connections, and mappings + +| Statement | Description | +|----------------------------------------------------|---------------------------------------| +| `ADD MAPPING FROM ''` | Load a graph mapping from a JSON file | +| `DROP MAPPING ` | Remove a mapping | +| `ADD CONNECTOR TYPE [options...]` | Register a backend connector | +| `DROP CONNECTOR ` | Remove a connector | +| `CONNECT AS [DEFAULT]` | Establish a named connection | +| `DISCONNECT ` | Close a connection | +| `PING ` | Test a connection is alive | +| `USE CONNECTION ` | Route a query to a specific connection| +| `SET DEFAULT CONNECTOR ` | Set session default connector | +| `SET DEFAULT CONNECTION ` | Set session default connection | +| `SHOW CONNECTORS` | List registered connectors | +| `SHOW CONNECTIONS` | List active connections | +| `SHOW MAPPINGS` | List loaded mappings | + +## Graph catalog + +``` +ADD GRAPH ON CONNECTOR + [GRAPH ] + [MAPPING ] + [READ ONLY]; + +CREATE GRAPH + [{ } | ANY] + ON CONNECTOR ; + +UNADD GRAPH [IF EXISTS] ; +DROP GRAPH [IF EXISTS] ; + +ALTER GRAPH SET READ ONLY; +ALTER GRAPH SET READ WRITE; +ALTER GRAPH SET CONNECTOR ; +ALTER GRAPH SET GRAPH ; +ALTER GRAPH SET MAPPING ; +ALTER GRAPH REMOVE MAPPING; + +SHOW GRAPHS; +SHOW GRAPHS ON CONNECTOR ; +SHOW GRAPH ; +``` + +`ADD GRAPH` registers an existing backend graph in the catalog; `CREATE GRAPH` both +registers it and creates it on the backend. See [Querying across +backends](/memgraph-zero/memgql/guides/querying-across-backends) for usage. + +## Routing across graphs + +``` +-- Single graph +USE ; + +-- Composite across graphs +USE +UNION | UNION ALL | INTERSECT | INTERSECT ALL | EXCEPT | EXCEPT ALL +USE ; +``` + +`USE` is optional — without it, MemGQL routes by matching the query's labels, +relationship types, and properties against the schema index (see +[automatic routing](/memgraph-zero/memgql/guides/querying-across-backends#automatic-routing-use-free)). + +## Schema introspection + +| Statement | Description | +|----------------------------|--------------------------------------------------------------------| +| `SHOW SCHEMA` | Print the global schema index — per source, the labels, properties, and relationship types MemGQL routes on | +| `SHOW SCHEMA FOR ` | The same, scoped to one graph | +| `REFRESH SCHEMA` | Re-introspect live Cypher connections and rebuild the index | + +`SHOW SCHEMA` is the discoverability surface for [agents](/memgraph-zero/memgql/guides/agents) +and what routing errors point at. Run `REFRESH SCHEMA` after a backend's schema changes.