LOAD FROM#

Reads an ordinary table or view into a Cypher pipeline, one working row per table row.

Synopsis#

LOAD FROM table_name AS alias

bold keywords · italic placeholders you supply · [ ] optional · ... repeatable. See Syntax conventions.

Description#

LOAD FROM is the relational source clause. It scans a table and binds each row to alias, whose columns are then readable as alias.column anywhere later in the pipeline. Because a graph and a table live in the same database, this needs no import step and no foreign-data wrapper.

  • The alias’s columns keep their SQL types. r.score on a numeric(3,1) column is a numeric, so r.score > 8.5 is a numeric comparison, not a jsonb one.

  • The alias itself is a row value. Projecting it gives the row as a jsonb object, so CREATE (:label = to_jsonb(alias)) is a whole-row load.

  • LOAD FROM may lead a query or follow another clause, and several may appear in one query. It never ends one.

  • The clause has no WHERE of its own. Filter with a following MATCH WHERE, a WITH WHERE, or a FILTER.

  • Anything a SELECT can read works: a table, a view, a schema-qualified name.

Parameters#

table_name

Name of the table or view to read, optionally schema-qualified. It must exist and be readable; an unknown name raises relation "..." does not exist.

alias

Name bound to each row. Read a column as alias.column, and the whole row as alias.

Examples#

Every example runs against the example dataset, which includes the ordinary table rating.

Read a table#

LOAD FROM rating AS r
RETURN r.title AS title, r.source AS source, r.score AS score
ORDER BY title, source
LIMIT 4;
        title        |  source   | score
---------------------+-----------+-------
 "Avatar"            | "critics" | 7.9
 "Blade Runner"      | "critics" | 8.1
 "Blade Runner 2049" | "critics" | 8.0
 "Elysium"           | "critics" | 6.6
(4 rows)

The values are quoted because a Cypher RETURN boxes its output columns to jsonb, not because the columns are jsonb. Their SQL types are unchanged:

LOAD FROM rating AS r RETURN pg_typeof(r.score) AS t LIMIT 1;
     t
-----------
 "numeric"
(1 row)

Join a table to the graph#

Load the table, then match against it. The relational column and the graph property are compared directly:

LOAD FROM rating AS r
MATCH (m:movie {title: r.title})
WHERE r.source = 'critics' AND r.score > 8.5
RETURN m.title AS film, m.year AS year, r.score AS score
ORDER BY score DESC;
             film             | year | score
------------------------------+------+-------
 "Inception"                  | 2010 | 8.8
 "The Matrix"                 | 1999 | 8.7
 "Interstellar"               | 2014 | 8.7
 "Terminator 2: Judgment Day" | 1991 | 8.6
(4 rows)

Read a whole row#

Project the alias by itself to get the row as a map:

LOAD FROM rating AS r RETURN r LIMIT 2;
                              r
-------------------------------------------------------------
 {"score": 8.7, "title": "The Matrix", "source": "critics"}
 {"score": 9.1, "title": "The Matrix", "source": "audience"}
(2 rows)

Read a view#

Any relation a SELECT can read is a valid source:

CREATE VIEW critic AS SELECT title, score FROM rating WHERE source = 'critics';
CREATE VIEW
LOAD FROM critic AS c
RETURN c.title AS film, c.score AS score
ORDER BY score DESC
LIMIT 3;
      film      | score
----------------+-------
 "Inception"    | 8.8
 "Interstellar" | 8.7
 "The Matrix"   | 8.7
(3 rows)
DROP VIEW critic;
DROP VIEW

Build vertices from table rows#

Name the properties you want:

CREATE TABLE tmp_people (name text, born int);
INSERT INTO tmp_people VALUES ('Ana Lily Amirpour', 1980), ('Rian Johnson', 1973);
CREATE TABLE
INSERT 0 2
LOAD FROM tmp_people AS t
CREATE (:person {name: t.name, born: t.born});
UPDATE 2

Or take the whole row as the property map, using = expression in place of a map literal:

LOAD FROM tmp_people AS t
CREATE (:person = to_jsonb(t));
UPDATE 2

Undo both loads and drop the table:

MATCH (p:person) WHERE p.name IN ['Ana Lily Amirpour', 'Rian Johnson'] DETACH DELETE p;
UPDATE 4
DROP TABLE tmp_people;
DROP TABLE

Notes#

LOAD FROM reads. It has no bulk-load machinery of its own, no parallel writer and no error routing. The CREATE that follows it inserts row by row through the graph write path. For loading a large table, and for the index and logging settings that make it faster, see loading data.

See also#

  • CREATE — the clause that turns loaded rows into vertices and edges

  • MATCH — joining loaded rows to the graph

  • WITH — filtering and aggregating loaded rows

  • Combining SQL and Cypher — the other direction, a Cypher query inside SQL

  • Loading data — the practical loading guide