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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions pages/memgraph-zero/memgql/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,29 @@ description: MemGQL release notes

## MemGQL v0.9.0 - August 9th, 2026

### 🍃 New features & Improvements

- **MongoDB connector.** New `mongodb` connector type brings a document store
into the federation. It is the first backend that is neither SQL nor Cypher:
queries are translated to **MongoDB aggregation pipelines** and executed
server-side. Node labels map to collections and relationship types to their own
collections holding `from`/`to` reference fields, using the same
[mapping](/memgraph-zero/memgql/reference#mapping-schema) format as every other
backend — a mapping written for PostgreSQL works unchanged. A single hop
becomes `$lookup`; a **variable-length hop becomes `$graphLookup`**, MongoDB's
native recursive traversal, so `(a)-[:KNOWS*1..3]->(b)` runs on the server —
and unlike the SQL backends the **unbounded** `*` form is supported too.
Filters that compare a property to a literal emit the plain query form so
MongoDB can serve them from an index. **Both reads and writes** are supported,
including `DETACH DELETE`, which clears incident edge documents. Connect with a
standard connection string, so replica sets and MongoDB Atlas
(`mongodb+srv://`) work as-is. `WITH` boundaries, `OPTIONAL MATCH` (including a
predicate inside the optional pattern), `FOR x IN […]`, and the full aggregate
set all run server-side; `UNION` and scalar functions inside `RETURN` are the
notable gaps. MongoDB runs the same cross-backend parity corpus as every other
connector, so its answers are checked against the same golden rows. See the
[MongoDB connector page](/memgraph-zero/memgql/connect/mongodb) for setup.

### ⚠️ Behavior changes

- **A vertex's or edge's `metaFields.id` is now exposed as a property.**
Expand Down
1 change: 1 addition & 0 deletions pages/memgraph-zero/memgql/connect.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ description: MemGQL connector details and configuration.
- [DuckDB](/memgraph-zero/memgql/connect/duckdb)
- [Iceberg](/memgraph-zero/memgql/connect/iceberg)
- [Memgraph](/memgraph-zero/memgql/connect/memgraph)
- [MongoDB](/memgraph-zero/memgql/connect/mongodb)
- [MySQL](/memgraph-zero/memgql/connect/mysql)
- [Neo4j](/memgraph-zero/memgql/connect/neo4j)
- [Oracle](/memgraph-zero/memgql/connect/oracle)
Expand Down
1 change: 1 addition & 0 deletions pages/memgraph-zero/memgql/connect/_meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export default {
"duckdb": "to DuckDB",
"iceberg": "to Iceberg",
"memgraph": "to Memgraph",
"mongodb": "to MongoDB",
"neo4j": "to Neo4j",
"oracle": "to Oracle",
"postgres": "to PostgreSQL",
Expand Down
222 changes: 222 additions & 0 deletions pages/memgraph-zero/memgql/connect/mongodb.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
---
title: MongoDB
description: Connect MemGQL to MongoDB.
---

# MongoDB

The MongoDB connector (`CONNECTOR_TYPE=mongodb`) translates GQL queries into
MongoDB **aggregation pipelines** and executes them on the server. It requires a
[mapping file](../quick-start.mdx#mapping-file) that maps graph patterns to
MongoDB collections.

Unlike the SQL connectors, nothing is translated to SQL. Node labels become
collections, relationship types become their own collections holding `from`/`to`
reference fields, and each GQL operator becomes a pipeline stage — a hop is
`$lookup`, and a variable-length hop is `$graphLookup`, MongoDB's native
recursive traversal.

## 1. Start MongoDB

```bash
docker network create memgql-net

docker run -d --rm \
--name mongodb-dev \
--network memgql-net \
-p 27017:27017 \
mongo:8
```

## 2. Seed data

```bash
docker exec -i mongodb-dev mongosh --quiet test << 'JS'
db.persons.insertMany([
{ id: 1, name: 'Alice', age: 30 },
{ id: 2, name: 'Bob', age: 25 },
]);
db.companies.insertOne({ id: 1, name: 'Acme Corp' });
db.knows.insertOne({ id: 1, from_id: 1, to_id: 2 });
db.works_at.insertOne({ id: 1, person_id: 1, company_id: 1 });

// Identity and endpoint indexes: `$lookup` and `$graphLookup` match on these,
// and without an index each hop is a collection scan.
db.persons.createIndex({ id: 1 }, { unique: true });
db.companies.createIndex({ id: 1 }, { unique: true });
db.knows.createIndex({ from_id: 1 });
db.knows.createIndex({ to_id: 1 });
db.works_at.createIndex({ person_id: 1 });
db.works_at.createIndex({ company_id: 1 });
JS
```

Check what landed, straight from `mongosh`:

```bash
docker exec mongodb-dev mongosh --quiet test --eval 'db.getCollectionNames().sort().forEach(c => print(c, JSON.stringify(db[c].find({}, {_id:0}).toArray())))'
```

```
companies [{"id":1,"name":"Acme Corp"}]
knows [{"id":1,"from_id":1,"to_id":2}]
persons [{"id":1,"name":"Alice","age":30},{"id":2,"name":"Bob","age":25}]
works_at [{"id":1,"person_id":1,"company_id":1}]
```

`persons` and `companies` are node collections; `knows` and `works_at` are edge
collections whose `from_id`/`to_id` and `person_id`/`company_id` point at node
`id`s. That reference shape is what the mapping below turns into a graph.

## 3. Start MemGQL

Create the mapping file the connector reads — labels over collections
(`vertices`), relationship types over edge collections (`edges`):

```bash
cat > mapping.json << 'EOF'
{
"vertices": [
{
"label": "Person",
"mappedTableSource": {
"table": "persons",
"metaFields": { "id": "id" }
},
"attributes": [{ "name": "name" }, { "name": "age" }]
},
{
"label": "Company",
"mappedTableSource": {
"table": "companies",
"metaFields": { "id": "id" }
},
"attributes": [{ "name": "name" }]
}
],
"edges": [
{
"label": "KNOWS",
"from": "Person",
"to": "Person",
"mappedTableSource": {
"table": "knows",
"metaFields": { "id": "id", "from": "from_id", "to": "to_id" }
}
},
{
"label": "WORKS_AT",
"from": "Person",
"to": "Company",
"mappedTableSource": {
"table": "works_at",
"metaFields": { "id": "id", "from": "person_id", "to": "company_id" }
}
}
]
}
EOF
```

```bash
docker run --rm \
--name memgql \
--network memgql-net \
--stop-timeout 2 \
-p 7688:7688 \
--env CONNECTOR_TYPE=mongodb \
--env MONGODB_URL=mongodb://mongodb-dev:27017 \
--env MONGODB_DB=test \
--env MAPPING_FILE=/data/mapping.json \
--env BOLT_LISTEN_ADDR=0.0.0.0:7688 \
--mount type=bind,source="$PWD/mapping.json",target=/data/mapping.json,readonly \
memgraph/memgql:latest
```

## 4. Connect

```bash
mgconsole --port 7688
```

## 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;
```

Variable-length traversal runs natively on MongoDB, and — unlike the SQL
connectors — the unbounded form works too:

```gql
MATCH (a:Person) (-[:KNOWS]->()){1,3} (b:Person) RETURN a.name, b.name;
```

For environment variables, see [Reference](../reference.mdx#mongodb-mongodb).

## Mapping a document model

The mapping file is the same one every other connector uses; only the field
names read differently:

| Mapping field | MongoDB meaning |
|----------------------------|------------------------------------------------|
| `mappedTableSource.schema` | database (defaults to `MONGODB_DB`) |
| `mappedTableSource.table` | collection |
| `metaFields.id` | identity field (often `_id`) |
| `metaFields.from` / `.to` | endpoint reference fields on an edge collection |
| `attributes[].column` | backing document field |

Relationships must live in their own collections carrying the `from`/`to`
reference fields — that is the shape `$lookup` and `$graphLookup` consume. A
model that embeds neighbours as an array inside the node document is not
supported.

Every collection in one graph must be in the same database: MongoDB's `$lookup`
resolves collections inside the aggregation's own database and cannot join
across databases. Spanning two databases needs two connectors.

## Supported GQL features

| Feature | MongoDB |
|------------------------------------------------|------------------------|
| `MATCH (n:Label) RETURN n.prop` | ✓ |
| Whole-node `RETURN n` / whole-rel `RETURN r` | ✓ |
| Pattern-level `WHERE` (`MATCH (n WHERE …)`) | ✓ |
| Typed edge `(a)-[r:R]->(b)` | ✓ (`$lookup`) |
| Variable-length `(-[:R]->()){m,n}` | ✓ (`$graphLookup`) |
| Unbounded variable-length `(-[:R]->()){m,}` | ✓ |
| `OPTIONAL MATCH` (incl. a predicate inside it) | ✓ |
| `WITH` pipeline boundaries | ✓ |
| `FOR x IN [...]` | ✓ |
| `ORDER BY` / `LIMIT` / `SKIP` | ✓ |
| `DISTINCT` | ✓ |
| Aggregation (`count`, `sum`, `avg`, `collect`) | ✓ (`$group`) |
| `INSERT (a {…})` | ✓ |
| `DELETE` / `DETACH DELETE` | ✓ |
| `SET` / `REMOVE` (properties) | ✓ |
| `SET` / `REMOVE` (labels) | ✗ — a label is a collection |
| `UNION` / `UNION ALL` | ✗ |
| Scalar functions in `RETURN` (`upper(x)`, …) | ✗ — see below |
| Untyped edge `(a)-[]->(b)` | ✗ — name the edge type |
| Undirected variable-length `(-[:R]-()){m,n}` | ✗ — give it a direction |
| Path binding on a quantified pattern | ✗ |

Traversal is reachability-based: `$graphLookup` returns the set of nodes
reachable through the edge collection, so a node reachable by several routes
appears once. Queries that count distinct paths need a Cypher backend.

Scalar functions inside `RETURN` (`upper(n.name)`, `abs(-7)`, `char_length(s)`)
are not available on MongoDB. The other backends receive such a call as raw
query text and evaluate it in their own dialect; an aggregation pipeline has no
expression string to run, so the function has to be applied client-side for now.
Aggregates (`count`, `sum`, `avg`, `min`, `max`, `collect`, and their `DISTINCT`
forms) are unaffected and run natively as `$group`.
2 changes: 2 additions & 0 deletions pages/memgraph-zero/memgql/features.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ description: MemGQL Community and Enterprise feature comparison.
|----------------------------------------------------------------------------------------------------------|-----------|-----------------------------------------------|
| GQL to Cypher translation | Yes | Yes |
| GQL to SQL translation | Yes | Yes |
| GQL to MongoDB aggregation pipeline translation | Yes | Yes |
| Bolt protocol | Yes | Yes |
| **Connectors** | | |
| [Memgraph](/memgraph-zero/memgql/connect/memgraph) | Yes | Yes |
Expand All @@ -23,6 +24,7 @@ description: MemGQL Community and Enterprise feature comparison.
| [Oracle](/memgraph-zero/memgql/connect/oracle) | Yes | Yes |
| [SQL Server](/memgraph-zero/memgql/connect/sqlserver) | Yes | Yes |
| [Snowflake](/memgraph-zero/memgql/connect/snowflake) | Yes | Yes |
| [MongoDB](/memgraph-zero/memgql/connect/mongodb) | Yes | Yes |
| **Multi-Connection Mode** | Yes | Yes |
| Max connectors | 2 | Unlimited |
| Max simultaneous connections | 2 | Unlimited |
Expand Down
4 changes: 2 additions & 2 deletions pages/memgraph-zero/memgql/multiple-graphs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ If you want a running stack to try these queries against, the [Docker Compose -

## Where the catalog DSL works

The catalog statements (`ADD CONNECTOR`, `CREATE GRAPH`, `SHOW GRAPHS`, `SHOW CONNECTORS`, `DROP GRAPH`, `USE <graph>`, …) are available in **`CONNECTOR_TYPE=multi`** mode. Single-backend modes (`memgraph-gql`, `neo4j-gql`, `postgres`, `mysql`, `oracle`, `duckdb`, `clickhouse`, `iceberg`, `pinot`, `snowflake`) connect to one backend configured via env vars and don't expose the catalog.
The catalog statements (`ADD CONNECTOR`, `CREATE GRAPH`, `SHOW GRAPHS`, `SHOW CONNECTORS`, `DROP GRAPH`, `USE <graph>`, …) are available in **`CONNECTOR_TYPE=multi`** mode. Single-backend modes (`memgraph-gql`, `neo4j-gql`, `postgres`, `mysql`, `oracle`, `duckdb`, `clickhouse`, `iceberg`, `pinot`, `snowflake`, `mongodb`) connect to one backend configured via env vars and don't expose the catalog.

| Statement | `multi` | Cypher single-backend | SQL single-backend |
|---|---|---|---|
Expand Down Expand Up @@ -84,7 +84,7 @@ MATCH (me:Person {id: 1})-[:FRIEND_OF]->(f:Person) RETURN f.id;
The schema index is built from two sources:

- **SQL-family connectors** (PostgreSQL, MySQL, Oracle, DuckDB, ClickHouse,
Iceberg, Pinot, Snowflake): taken from the registered **mapping** (labels,
Iceberg, Pinot, Snowflake, MongoDB): taken from the registered **mapping** (labels,
rel-types, and properties are known exactly).
- **Cypher-family connectors** (Memgraph, Neo4j): **introspected at `CONNECT`
time** and cached. Memgraph uses `SHOW SCHEMA INFO` (the server must run with
Expand Down
Loading