Schema File

MemGQL federates one or more backends behind a single Bolt endpoint and exposes them as named graphs you query with GQL / openCypher. A schema file is the one place that declares both halves of that setup:

A connector is a connection. A graph is a mapping laid over connectors. You query graphs; routing figures out which backend to hit.

Everything in the file can also be created at runtime with DDL; the schema file is the boot-time equivalent, and runtime changes persist back to it.

Booting from a schema file

Run MemGQL in Docker: mount the schema file and pass its container path.

docker run --rm -p 7688:7688 \
  -v "$(pwd)/schema.json:/data/schema.json" \
  memgraph/memgql:latest --schema=/data/schema.json

--schema (or the SCHEMA_FILE env var) is all you need; it implies multi-connector mode. MemGQL listens on 0.0.0.0:7688 by default — every interface, as Memgraph does — so the published port reaches it without further configuration. To accept local connections only, set BOLT_LISTEN_ADDR=127.0.0.1:7688 or pass --bolt-address=127.0.0.1 (see Configuration). Run MemGQL on the same Docker network as the backends its connectors reference.

Every connector connects and every graph registers at boot, so no CONNECT or USE is required to start querying. Runtime DDL writes the updated catalog back to this file atomically, so a restart reloads the same state with no replay (credentials stay on disk but are masked in EXPORT SCHEMA).

The file is validated at boot. A malformed mapping (for example a relational edge missing metaFields.from / metaFields.to, or the legacy nodes / id_column format) is rejected with an actionable error before the server starts serving.

The file has two top-level sections:

{
  "connectors": [],
  "graphs": []
}

An optional _comment string is allowed at the top level and on each graph for free-text notes; it is ignored at load.

A minimal schema

The smallest useful file is one connector and one vertex: a label mapped to a table by its primary-key column.

{
  "connectors": [
    {
      "name": "pg",
      "type": "postgres",
      "connection": {
        "uri": "postgresql://demo:demo@localhost:5432/demo"
      }
    }
  ],
  "graphs": [
    {
      "name": "store",
      "vertices": [
        {
          "label": "Product",
          "mappedTableSource": {
            "connector": "pg",
            "table": "products",
            "metaFields": {
              "id": "pid"
            }
          },
          "attributes": [
            {
              "name": "pid",
              "type": "Int"
            },
            {
              "name": "title"
            }
          ]
        }
      ]
    }
  ]
}

Boot it, then query the label by name:

MATCH (p:Product) RETURN p.title LIMIT 5;

The sections below are the full field reference for each block.

connectors

A connector is a pure connection: how to reach a backend, and nothing about graph shape. catalogs is accepted as an alias for connectors.

{
  "connectors": [
    {
      "name": "pg",
      "type": "postgres",
      "connection": {
        "uri": "postgresql://user:pass@host:5432/db"
      }
    }
  ]
}
FieldRequiredDescription
nameyesReferenced by graphs and DDL.
typeyesBackend type (see below).
connectionyesA native connection block (see fields below). JDBC-style keys (jdbc, driverClass, …) are rejected.

Every connection field is optional; supply what a given backend needs:

connection fieldUsed for
uriConnection string for the backend.
user / passwordCredentials (override / complement the URI).
databaseDatabase name. On memgraph / neo4j it selects the Bolt database (multi-tenancy), the same thing ADD CONNECTOR … GRAPH <db> selects at runtime, so one instance can back several connectors; EXPORT SCHEMA writes a runtime GRAPH selector back as database.
schemaMiddle namespace (PostgreSQL schema, MySQL / ClickHouse database, Iceberg schema).
catalogNative root for three-level backends (Iceberg catalog, SQL Server database, Fabric warehouse/lakehouse item).
pathFile-backed backends (DuckDB).
sslRootCertPEM bundle of CA certificates to trust instead of the system roots (PostgreSQL).
trustServerCertificateEncrypt without verifying the server’s certificate (PostgreSQL). Mutually exclusive with sslRootCert.
warehouse / roleSnowflake session context. Each falls back to its SNOWFLAKE_* environment variable when omitted.
private_key_path / tokenSnowflake key-pair or token authentication instead of a password. Each falls back to its SNOWFLAKE_* environment variable when omitted.
tenant_id / client_id / client_secretMicrosoft Fabric service-principal authentication. Each falls back to its FABRIC_* environment variable when omitted.
languageDefault query language (gql / cypher) for USE <graph> queries whose graph maps to this connector.
maxInListSizeMost join-key values sent to this backend in one piped cross-backend join; the same as ADD CONNECTOR … OPTIONS '{"max_in_list_size": N}'.

Supported type values: memgraph, neo4j, postgres (postgresql), mysql, sqlserver, oracle, duckdb, iceberg, iceberg-direct, clickhouse, pinot, snowflake, mongodb, fabric, hana, redshift.

For PostgreSQL, the TLS mode stays in the URI (sslmode=), where libpq users expect it; sslRootCert / trustServerCertificate declare what a URI cannot express. See TLS connections.

graphs

Each graph is a set of vertices and edges laid over the shared connectors. A single graph may span several connectors.

{
  "graphs": [
    {
      "name": "store",
      "vertices": [],
      "edges": []
    }
  ]
}

Single-graph shorthand: put vertices / edges at the top level instead of a graphs block and you get one implicit graph named default.

Access mode

A graph entry optionally declares "accessMode": "readOnly" | "readWrite" (default readWrite). Writes routed to a read-only graph are refused before any backend sees them; an unknown value is refused at load, so a typo cannot silently leave a replica writable. ALTER GRAPH <name> SET READ ONLY | READ WRITE flips the mode at runtime and persists it back to this file; EXPORT SCHEMA round-trips it.

{
  "name": "benchling_replica",
  "accessMode": "readOnly",
  "vertices": [],
  "edges": []
}

Discovered native schema

A Memgraph or Neo4j connector already knows its own labels, relationship types and properties, so a graph does not have to repeat them. List the connector under discover and its schema is read at boot and on REFRESH SCHEMA: every node type becomes a vertex, with the label set spelled A:B and the introspected properties as attributes, and every relationship type becomes one edge per (type, start labels, end labels) pair.

{
  "name": "shop",
  "accessMode": "readOnly",
  "discover": ["mg"],
  "vertices": [
    {
      "label": "Item",
      "mappedTableSource": { "connector": "pg", "table": "item", "metaFields": { "id": "item_key" } },
      "attributes": [{ "name": "sku" }]
    }
  ],
  "edges": [
    {
      "label": "catalogEntry",
      "from": "Item",
      "to": "CAT:Product",
      "mappedJoinSource": { "fromKey": "sku", "toKey": "sku" }
    }
  ]
}

What the graph declares itself wins: a declared vertex (matched by its label set) keeps its attributes and renames, and a declared relationship type keeps exactly its declared pairs, so declaring an element is how you restrict or refine what discovery exposes. An edge may name a vertex that is discovered later, as above, as long as exactly one connector is discovered from. EXPORT SCHEMA and the persisted file write the discover entry back, not the discovered elements. Memgraph must run with --schema-info-enabled; discover is refused on a relational connector (declare the tables, or draft them with GENERATE MAPPING FOR CONNECTOR).

Vertices

A vertex maps a label to a backend source. Exactly one source kind is set:

  • mappedTableSource: a relational table (PostgreSQL, MySQL, Oracle, SQL Server, DuckDB, ClickHouse, Iceberg). Rows become nodes.
  • mappedGraphSource: a native graph backend (Memgraph / Neo4j). Queries pass through as Cypher; only the connector is declared, plus label when the backend stores the element under another name.

A vertex may also add a mappedContentSource on top of either one, to read some of its properties from a table in another connector (see Content in another connector).

{
  "label": "Customer",
  "mappedTableSource": {
    "connector": "pg",
    "schema": "public",
    "table": "customers",
    "metaFields": {
      "id": "cid"
    }
  },
  "attributes": [
    {
      "name": "cid",
      "type": "Int"
    },
    {
      "name": "name",
      "column": "full_name"
    },
    {
      "name": "email",
      "type": "String"
    }
  ]
}
{
  "label": "User",
  "mappedGraphSource": {
    "connector": "mg"
  },
  "attributes": [
    {
      "name": "uid",
      "type": "Int"
    },
    {
      "name": "handle"
    }
  ]
}

A table whose rows should carry more than one label lists them under labels instead of label. The first label identifies the mapping and must be unique in the graph; the others may be shared with other mappings:

{
  "labels": ["Cat", "Animal"],
  "mappedTableSource": {
    "connector": "pg",
    "table": "cats",
    "metaFields": { "id": "cat_id" }
  },
  "attributes": [
    { "name": "id", "column": "cat_id" },
    { "name": "name" }
  ]
}

With a second mapping ["Dog", "Animal"] over a dogs table keyed by dog_id, MATCH (a:Cat) reads one table, MATCH (a:Dog&Animal) the other (GQL writes a label conjunction as :A&B; in Cypher it is :Dog:Animal), and MATCH (a:Animal) both — as one UNION statement inside the connector. Shared property names resolve through each table’s own columns, a property only one table declares is null on the other’s rows, and returned nodes carry all of their labels ((:Cat:Animal)). Attributes that two carriers of a shared label both declare must have the same type. A traversal or an INSERT has to start from one table, so on a shared label both are refused with a pointer to the identifying label. A label no mapping carries together with the others matches nothing.

A native node type that carries several labels is one vertex spelled with a colon, "label": "CAT:Product", and written backticked in GQL (MATCH (p:`CAT:Product`)). Each member label routes as well: MATCH (p:CAT) reads every CAT node whatever its other labels, MATCH (p:CAT&`Product`) and Cypher’s MATCH (p:CAT:Product) reach the same vertex, and a backticked :`CAT:Product` in a CYPHER passthrough is sent to the backend as the label conjunction :CAT:Product. This is also the spelling schema discovery produces.

FieldSource kindDescription
label / labelsbothThe 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.
mappedTableSource.connectorrelationalConnector name (alias catalog).
mappedTableSource.schemarelationalOptional middle namespace (PostgreSQL schema, etc.).
mappedTableSource.databaserelationalOptional 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.
mappedTableSource.tablerelationalThe backing table or view.
mappedTableSource.metaFields.idrelationalPrimary-key column, or a list of columns for a composite key (["region", "order_no"]); the node’s identity and the join key for edges. Each column is also exposed as a property, so RETURN n includes it and n.<id_column> reads it by name.
mappedGraphSource.connectornativeConnector name (Memgraph / Neo4j); the query passes through as Cypher.
mappedGraphSource.labelnativeOptional backend label (on an edge, backend relationship type) exposed under this element’s label. Queries use the exposed name, MemGQL rewrites it for the backend, and returned nodes and relationships carry the exposed name. Two elements cannot share a backend name. Not renamed: strings a query computes from names (labels(n), type(r)), the extra labels of a multi-label vertex, and property keys.
mappedContentSourceeitherOptional second source for some of the vertex’s properties; see Content in another connector.
attributeseitherThe properties the vertex exposes; see Attributes.

Content in another connector

A vertex can keep its identity, edges and a few frequently read properties in one connector while its bulky properties (long text, documents, payloads) live in a table in another connector, keyed by the same value. Queries still see one vertex with every property.

{
  "label": "Ticket",
  "mappedGraphSource": { "connector": "mg" },
  "attributes": [
    { "name": "ticketId" },
    { "name": "priority" }
  ],
  "mappedContentSource": {
    "connector": "pg",
    "table": "ticket_content",
    "key": "ticketId",
    "keyColumn": "ticket_id",
    "attributes": [
      { "name": "subject" },
      { "name": "description", "column": "body" }
    ]
  }
}
MATCH (t:Ticket)-[:ASSIGNED_TO]->(a:Agent)
WHERE t.subject CONTAINS 'login'
RETURN t.ticketId, t.description, a.name;

The content table is read only when a query filters on or returns one of its properties. MemGQL then joins it in by key, fetching the matching rows in one batch: a filter on a content property is evaluated in the content connector first, and a plain projection is read after the traversal for exactly the vertices it found. A query that touches no content property never reaches the content connector.

mappedContentSource keyRequiredDescription
connectoryesA relational connector, different from the vertex’s own.
schemanoMiddle namespace of the content table.
tableyesThe content table.
keyyesA property declared in the vertex’s own attributes; its value finds the content row.
keyColumnnoThe column in the content table that holds the key value. Defaults to key.
attributesyesThe properties read from the content table, declared like Attributes; column and path refer to the content table.

Rules and limits (each is refused with a message saying what to write instead):

  • Each property has exactly one home: a name may not appear both in the vertex’s attributes and in the content attributes, and the key is declared only on the vertex.
  • The content connector must be relational and differ from the vertex’s connector. Content in the same connector is just more attributes.
  • A query that reads content properties must be a single MATCH … RETURN: no WITH, UNWIND, CALL, UNION or RETURN *, and OPTIONAL MATCH may not bind the vertex whose content is read.

Edges

An edge maps a relationship type between two labels. Relational edges name the foreign-key columns via metaFields.from / metaFields.to; native-graph edges pass through; and a mappedJoinSource edge has no table at all — it links two labels by the equality of one property on each side, whether they live in different connectors or in the same one (see Cross-connector edges). Exactly one source kind is set. An edge’s from / to name a vertex by its identifying label (the first entry of a labels list).

{
  "label": "PURCHASED",
  "from": "Customer",
  "to": "Product",
  "mappedTableSource": {
    "connector": "pg",
    "table": "orders",
    "metaFields": {
      "id": "oid",
      "from": "cid",
      "to": "pid"
    }
  },
  "attributes": [
    {
      "name": "qty",
      "type": "Int"
    }
  ]
}
{
  "label": "FOLLOWS",
  "from": "User",
  "to": "User",
  "mappedGraphSource": {
    "connector": "mg"
  }
}
FieldDescription
labelThe relationship type.
from / toThe identifying labels of the source and target vertex.
mappedTableSource / mappedGraphSource / mappedJoinSourceWhere the edge lives; exactly one is set.
attributesEdge properties; see Attributes. Not allowed on a mappedJoinSource edge.

A native relationship type is often used between several label pairs. Declare it once per pair; this is the one case where an edge label repeats within a graph (a table-backed edge label stays unique):

{ "label": "inGroup", "from": "CAT:Product", "to": "CAT:Group", "mappedGraphSource": { "connector": "mg" } },
{ "label": "inGroup", "from": "CAT:Product", "to": "CAT:Note",  "mappedGraphSource": { "connector": "mg" } }

The declared ends also constrain a pattern end you leave bare: MATCH (p:`CAT:Product`)-[:inGroup]->(g) reaches the backend as (g:CAT:Group) with one pair declared and as WHERE g:CAT:Group OR g:CAT:Note with two, never as an unconstrained (g) that would return nodes of labels the graph does not declare.

A relational edge adds two more metaFields on top of id:

metaFields keyDescription
idThe edge row’s own key. Exposed as a property, like a vertex’s.
fromForeign-key column pointing at the source vertex’s id column.
toForeign-key column pointing at the target vertex’s id column.

Each key is a column name or a list of column names. A list declares a composite key and is matched positionally against the endpoint’s id list, so "to": ["region", "order_no"] requires the target vertex to declare "id": ["region", "order_no"]; a length mismatch is refused at load. The join is pushed down column by column (… AND r.region = o.region AND r.order_no = o.order_no).

from and to are required on relational edges; they define the traversal (from)-[:LABEL]->(to). Loading fails with an actionable error if either is missing. Native-graph edges (mappedGraphSource) need only from / to labels; the traversal is resolved by the backend.

Cross-connector edges

A third source kind, mappedJoinSource, declares an edge with no backing table anywhere: the relationship is equality between one property on each endpoint. It is how a traversal crosses into a different connector, and also how two tables in the same connector are linked by a business key rather than by a foreign key into the target’s metaFields.id.

{
  "label": "MANUFACTURED_BY",
  "from": "Component",
  "to": "Manufacturer",
  "mappedJoinSource": {
    "fromKey": "manufacturer_code",
    "toKey": "code"
  }
}

With Component mapped to a PostgreSQL table and Manufacturer to a Memgraph connector, one pattern now traverses the boundary:

MATCH (c:Component)-[:MANUFACTURED_BY]->(m:Manufacturer) RETURN c.sku, m.name;
mappedJoinSource keyDescription
fromKeyProperty on the from vertex. A GQL property name, not a raw column; it resolves through that vertex’s own mapping.
toKeyProperty on the to vertex, resolved the same way.

This is the only edge form that works when one endpoint is a native-graph backend, which has no joinable edge table to point at. Under the hood the traversal is rewritten into the cross-backend join that already runs — one part per connector plus the join equality — so piping, per-part caching and the local join all apply unchanged.

RETURN c, r, m packs real nodes and a relationship, so graph clients such as Memgraph Lab can draw and expand the result. Element ids are synthesized from the connector, label and key, so two backends that both number rows from 1 don’t collide.

Rules and limits (each is refused with a message saying what to write instead):

  • Each key must be a declared attribute of its endpoint vertex, backed by a plain scalar column (native-graph vertices are exempt, since the query passes through). The edge declares no attributes.
  • The edge carries no properties, so it cannot be filtered — filter the endpoints instead.
  • Across connectors: the edge must be traversed in a direction (-[:R]-> or <-[:R]-, not -[:R]-); no variable-length traversal, no OPTIONAL MATCH, one MATCH with one path pattern per query; every node in the pattern needs a label, so each side can be routed.
  • Within one relational connector the edge is pushed down as a single JOIN on the two key columns, so those limits do not apply: aggregates work, and an undirected step is accepted when the two endpoint labels differ. A variable-length step over it is refused. Both endpoints on a Memgraph or Neo4j connector are refused — that backend stores its own relationships, so declare mappedGraphSource.

A table-backed edge whose endpoints sit in different connectors is still skipped at load time with a warning pointing at mappedJoinSource.

Attributes

attributes declare the properties a label exposes.

FieldRequiredDescription
nameyesThe GQL property name.
columnnoThe backing column (defaults to name), e.g. property name ← column full_name.
typenoRecorded, not enforced at query time (default String).
pathnoLocation inside a JSON document column (see below).

Allowed type values: Boolean, Byte, Short, Int, Long, HugeInt, Float, Double, Decimal, String, Date, DateTime, Json.

JSON / JSONB columns

A document column (PostgreSQL JSONB, MySQL JSON, …) can be mapped two ways, and they compose — use both on the same column.

Declared path. Pin a value inside the document to its own typed property. column names the document column, path the location inside it, and type the type of the value found there:

{
  "name": "voltage",
  "column": "props",
  "path": "electrical.voltage",
  "type": "Double"
}
MATCH (c:Component) WHERE c.voltage > 240 RETURN c.voltage;

pushes down to the source as an extraction cast to the declared type. The cast is what makes the comparison numeric — without it the database compares text, where '90' > '240'. path is a dotted string; for keys that themselves contain a dot, write an explicit segment list: "path": ["spec.v2", "voltage"].

Passthrough. Mark the column Json and it stays a document: RETURN c.props returns a map, and undeclared keys are reachable with ordinary property syntax — c.props.rohs, c.props.electrical.voltage — each pushed down as an extraction on the source. This is the option for heterogeneous blobs where declaring every key up front isn’t possible. An undeclared key carries no declared type, so the comparison supplies one: compared against a number it is cast like a declared numeric path, compared against a string it stays text. A key the document doesn’t have reads as null rather than failing the query, and so does one whose parent is missing or isn’t an object (c.props.nosuch.deeper). Filtering on an absent key matches no rows — including a numeric comparison, where the cast applies to nothing. Returned, sorted or used in arithmetic, an undeclared key keeps its JSON type on PostgreSQL and MySQL (true, 3, 150.5); the other backends return it as text.

{ "name": "props", "type": "Json" }

Limits. path attributes are read-only — an INSERT through a JSON path is rejected rather than clobbering the surrounding document. JSON path support is per backend: PostgreSQL, MySQL, DuckDB, SQL Server, Microsoft Fabric and Snowflake. A mapping that declares a path against any other connector fails to load, so the mismatch surfaces at boot / CREATE GRAPH rather than on every query.

attributes are optional and need not be exhaustive: a property you don’t list still resolves to a same-named column at query time (p.sku → column sku). Declare the ones you want to rename (column), give a type, or route queries by.

Note: for routing to match a query by property (e.g. WHERE c.email = …), the property must be a declared attribute. Route by label or relationship type, or add an explicit USE, when a property isn’t declared. See routing.

Note: caching a graph follows the same rule. The cache holds a label’s id and its declared attributes, so a query reading an undeclared property is served from the source rather than from the cache. A label declaring no attributes still caches its ids and topology, which is what traversals and graph algorithms run on.

Complete example

One engine over Memgraph (a social graph) and PostgreSQL (a store), sharing a uid / cid id space so you can query each on its own or join across them.

{
  "connectors": [
    {
      "name": "mg",
      "type": "memgraph",
      "connection": {
        "uri": "bolt://localhost:7687"
      }
    },
    {
      "name": "pg",
      "type": "postgres",
      "connection": {
        "uri": "postgresql://demo:demo@localhost:5432/demo"
      }
    }
  ],
  "graphs": [
    {
      "name": "social",
      "vertices": [
        {
          "label": "User",
          "mappedGraphSource": {
            "connector": "mg"
          },
          "attributes": [
            {
              "name": "uid",
              "type": "Int"
            },
            {
              "name": "handle"
            },
            {
              "name": "name"
            }
          ]
        }
      ],
      "edges": [
        {
          "label": "FOLLOWS",
          "from": "User",
          "to": "User",
          "mappedGraphSource": {
            "connector": "mg"
          }
        }
      ]
    },
    {
      "name": "store",
      "vertices": [
        {
          "label": "Customer",
          "mappedTableSource": {
            "connector": "pg",
            "table": "customers",
            "metaFields": {
              "id": "cid"
            }
          },
          "attributes": [
            {
              "name": "cid",
              "type": "Int"
            },
            {
              "name": "name",
              "column": "full_name"
            },
            {
              "name": "email"
            }
          ]
        },
        {
          "label": "Product",
          "mappedTableSource": {
            "connector": "pg",
            "table": "products",
            "metaFields": {
              "id": "pid"
            }
          },
          "attributes": [
            {
              "name": "pid",
              "type": "Int"
            },
            {
              "name": "title"
            },
            {
              "name": "price",
              "type": "Double"
            }
          ]
        }
      ],
      "edges": [
        {
          "label": "PURCHASED",
          "from": "Customer",
          "to": "Product",
          "mappedTableSource": {
            "connector": "pg",
            "table": "orders",
            "metaFields": {
              "id": "oid",
              "from": "cid",
              "to": "pid"
            }
          },
          "attributes": [
            {
              "name": "qty",
              "type": "Int"
            }
          ]
        }
      ]
    }
  ]
}

Boot it, then query by label:

MATCH (u:User) RETURN u.handle, u.name ORDER BY u.uid LIMIT 5;
MATCH (c:Customer)-[:PURCHASED]->(p:Product) RETURN c.name, p.title;
MATCH (p:Product) WHERE p.price > 100 RETURN p.title ORDER BY p.price DESC;

The shared uid / cid id space also lets one query join across both backends. See Multiple Graphs for the full query model (routing, cross-backend joins, and composites) and Reference for the runtime DDL that builds the same catalog live.

How it works

  • Connector = connection, graph = mapping. A graph maps labels and relationship types onto one or more connectors, so a single graph can span backends.
  • Routing by label. At boot (and on REFRESH SCHEMA) the engine tracks which graph defines each label. A query with no USE routes by the labels and declared properties it mentions; anything ambiguous returns an actionable error rather than a silent guess.

Glossary

Every name a schema file can contain, grouped by where it appears.

Top level

NameMeaning
connectorsThe backends to connect to, shared by all graphs. Alias: catalogs.
graphsNamed graphs, each with its own vertices and edges.
vertices / edgesAt the top level instead of graphs: one implicit graph named default.
_commentFree-text note, allowed at the top level and on a graph.

Connector (connectors[])

NameMeaning
nameThe id sources use to point at this connector.
typeBackend kind, for example postgres or memgraph.
connectionHow to reach the backend.
connection.uri / pathConnection string, or a file location for file-backed backends.
connection.user / passwordCredentials.
connection.database / schema / catalogThe physical namespace the connection defaults to.
connection.warehouse / role / private_key_path / tokenSnowflake session context and authentication.
connection.tenant_id / client_id / client_secretMicrosoft Fabric service-principal authentication.
connection.languageDefault query language (gql / cypher) for graphs on this connector.
connection.sslRootCert / trustServerCertificateTLS trust settings.
connection.maxInListSizeMost join-key values sent in one cross-backend IN list.

Graph (graphs[])

NameMeaning
nameThe graph name, as in USE <name>.
vertices / edgesThe graph’s elements.
accessModereadOnly or readWrite (default).
discoverNative connectors whose labels and relationship types are added automatically.

Vertex

NameMeaning
labelThe exposed node label; unique within a graph.
labelsSeveral labels; the first identifies the mapping, the rest may be shared.
mappedTableSource / mappedGraphSourceWhere the vertex lives; exactly one is set.
mappedContentSourceOptional table in another connector for some of its properties.
attributesThe properties read from the vertex’s own source.

Edge

NameMeaning
labelThe relationship type.
from / toThe labels of the source and target vertex.
mappedTableSource / mappedGraphSource / mappedJoinSourceWhere the edge lives; exactly one is set.
attributesEdge properties; not allowed with mappedJoinSource.

Sources

NameMeaning
mappedTableSourceA table in a relational connector.
↳ connectorWhich connector. Alias: catalog.
↳ schema / databasePer-element override of the physical namespace.
↳ tableTable, view or collection.
↳ metaFields.idColumn(s) identifying a row; a list for a composite key.
↳ metaFields.from / toEdges: column(s) holding the source and target vertex’s id.
mappedGraphSourceA label or relationship type in a native graph connector.
↳ connectorWhich connector. Alias: catalog.
↳ labelThe backend’s own name, when it differs from the exposed one.
mappedContentSourceSome of a vertex’s properties, read from a table in another connector.
↳ connector / schema / tableWhere the content table is.
↳ keyThe vertex property the content row is found by.
↳ keyColumnThe content-table column holding the key value.
↳ attributesProperties read from the content table.
mappedJoinSourceAn edge that exists where two property values are equal.
↳ fromKey / toKeyProperties on the from and to vertex.

Attribute (attributes[])

NameMeaning
nameThe exposed property name.
typeDeclared type, default String; Json makes the column descendable.
columnThe source column; defaults to name.
pathLocation of the value inside a JSON column.

Names with more than one meaning

NameWhereMeans
catalogtop levelalias for connectors
in a source blockalias for connector
in connectionthe backend’s physical catalog
from / toon an edgevertex labels
in metaFieldscolumns
labelon an elementthe exposed name
in mappedGraphSourcethe backend’s name
schema / databasein connectionthe connection-wide default
in a source blockan override for that element
pathin connectiona file location
on an attributea location inside a JSON column

Key fields name either a column or a property: metaFields.* and keyColumn take columns of the source table; key, fromKey and toKey take property names, which resolve through the element’s attributes.