You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 0973e12
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: pages/memgraph-zero/memgql/schema-file.mdx
+51-14Lines changed: 51 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -245,8 +245,40 @@ A vertex maps a **label** to a backend source. Exactly one source kind is set:
245
245
}
246
246
```
247
247
248
+
A table whose rows should carry **more than one label** lists them under
249
+
`labels` instead of `label`. The first label identifies the mapping and must be
250
+
unique in the graph; the others may be shared with other mappings:
251
+
252
+
```json
253
+
{
254
+
"labels": ["Cat", "Animal"],
255
+
"mappedTableSource": {
256
+
"connector": "pg",
257
+
"table": "cats",
258
+
"metaFields": { "id": "cat_id" }
259
+
},
260
+
"attributes": [
261
+
{ "name": "id", "column": "cat_id" },
262
+
{ "name": "name" }
263
+
]
264
+
}
265
+
```
266
+
267
+
With a second mapping `["Dog", "Animal"]` over a `dogs` table keyed by
268
+
`dog_id`, `MATCH (a:Cat)` reads one table, `MATCH (a:Dog&Animal)` the other
269
+
(GQL writes a label conjunction as `:A&B`; in Cypher it is `:Dog:Animal`),
270
+
and `MATCH (a:Animal)` both — as one `UNION` statement inside the connector.
271
+
Shared property names resolve through each table's own columns, a property
272
+
only one table declares is `null` on the other's rows, and returned nodes
273
+
carry all of their labels (`(:Cat:Animal)`). Attributes that two carriers of a shared
274
+
label both declare must have the same `type`. A traversal or an `INSERT` has to
275
+
start from one table, so on a shared label both are refused with a pointer to
276
+
the identifying label. A label no mapping carries together with the others
277
+
matches nothing.
278
+
248
279
| Field | Source kind | Description |
249
280
|-------|-------------|-------------|
281
+
|`label` / `labels`| both | The node label, or a list of labels whose first entry identifies the mapping (unique per graph) and whose others may be shared with other mappings. |
250
282
|`mappedTableSource.connector`| relational | Connector name (alias `catalog`). |
|`mappedTableSource.database`| relational | Optional outer namespace for backends with three-part names; on SQL Server it renders `database.schema.table`, so one connection can reach views in other databases. |
@@ -318,9 +350,11 @@ labels; the traversal is resolved by the backend.
318
350
319
351
#### Cross-connector edges
320
352
321
-
A third source kind, `mappedJoinSource`, declares an edge whose two endpoints
322
-
live in **different connectors**. It has no backing table anywhere: the
323
-
relationship *is* equality between one property on each endpoint.
353
+
A third source kind, `mappedJoinSource`, declares an edge with **no backing
354
+
table anywhere**: the relationship *is* equality between one property on each
355
+
endpoint. It is how a traversal crosses into a **different connector**, and
356
+
also how two tables in the **same** connector are linked by a business key
357
+
rather than by a foreign key into the target's `metaFields.id`.
324
358
325
359
```json
326
360
{
@@ -361,19 +395,22 @@ don't collide.
361
395
**Rules and limits** (each is refused with a message saying what to write
362
396
instead):
363
397
364
-
- Both endpoints must live in different connectors — within one connector use
365
-
`mappedTableSource` with `metaFields.from` / `to`.
366
-
- Each key must be a declared `attribute` of its endpoint vertex (native-graph
367
-
vertices are exempt, since the query passes through).
368
-
- The edge must be traversed **in a direction**: `-[:R]->` or `<-[:R]-`, not
369
-
`-[:R]-`.
370
-
- No variable-length traversal, no `OPTIONAL MATCH`, and one `MATCH` with one
371
-
path pattern per query.
398
+
- Each key must be a declared `attribute` of its endpoint vertex, backed by a
399
+
plain scalar column (native-graph vertices are exempt, since the query passes
400
+
through). The edge declares no `attributes`.
372
401
- The edge carries no properties, so it cannot be filtered — filter the
373
402
endpoints instead.
374
-
- Every node in the pattern needs a label, so each side can be routed.
375
-
- Aggregating *across* the join (for example `count()` over both sides) is not
376
-
supported yet; return the rows and count client-side.
403
+
- Across connectors: the edge must be traversed **in a direction** (`-[:R]->`
404
+
or `<-[:R]-`, not `-[:R]-`); no variable-length traversal, no
405
+
`OPTIONAL MATCH`, one `MATCH` with one path pattern per query; every node in
406
+
the pattern needs a label, so each side can be routed; aggregating *across*
407
+
the join (`count()` over both sides) is not supported yet.
408
+
- Within one relational connector the edge is pushed down as a single `JOIN`
409
+
on the two key columns, so those limits do not apply: aggregates work, and an
410
+
undirected step is accepted when the two endpoint labels differ. A
411
+
variable-length step over it is refused. Both endpoints on a Memgraph or
412
+
Neo4j connector are refused — that backend stores its own relationships, so
413
+
declare `mappedGraphSource`.
377
414
378
415
A **table-backed** edge whose endpoints sit in different connectors is still
379
416
skipped at load time with a warning pointing at `mappedJoinSource`.
0 commit comments