-- -- Cypher Query Language - DML -- -- prepare DROP TABLE IF EXISTS history; NOTICE: table "history" does not exist, skipping CREATE TABLE history (year, event) AS VALUES (1996, 'PostgreSQL'), (2016, 'Graph'); DROP GRAPH agens CASCADE; ERROR: graph "agens" does not exist CREATE GRAPH agens; -- -- RETURN -- RETURN 3 + 4, 'hello' + ' agens'; ?column? | ?column? ----------+--------------- 7 | "hello agens" (1 row) RETURN 3 + 4 AS lucky, 'hello' + ' agens' AS greeting; lucky | greeting -------+--------------- 7 | "hello agens" (1 row) RETURN (SELECT event FROM history WHERE year = 2016); event ------- Graph (1 row) SELECT * FROM (RETURN 3 + 4, 'hello' + ' agens') AS _(lucky, greeting); lucky | greeting -------+--------------- 7 | "hello agens" (1 row) -- -- zero-length _vertex, _edge, and graphpath -- SELECT ARRAY[]::_vertex; array ------- [] (1 row) SELECT ARRAY[]::_edge; array ------- [] (1 row) SELECT (ARRAY[]::_vertex, ARRAY[]::_edge)::graphpath; row ----- [] (1 row) -- -- _vertex, _edge, and graphpath with NULL values -- SELECT ARRAY[NULL, NULL, NULL]::_vertex; array ------------------ [NULL,NULL,NULL] (1 row) SELECT ARRAY[NULL, NULL]::_edge; array ------------- [NULL,NULL] (1 row) SELECT (ARRAY[NULL, NULL, NULL]::_vertex, ARRAY[NULL, NULL]::_edge)::graphpath; row ---------------------------- [NULL,NULL,NULL,NULL,NULL] (1 row) -- -- CREATE -- CREATE VLABEL repo; CREATE ELABEL lib; CREATE ELABEL doc; CREATE (g:repo {name: 'agens-graph', year: (SELECT year FROM history WHERE event = 'Graph')}) RETURN properties(g) AS g; g --------------------------------------- {"name": "agens-graph", "year": 2016} (1 row) MATCH (g:repo) CREATE (j:repo {name: 'agens-graph-jdbc', year: 2016}), (d:repo {name: 'agens-graph-docs', year: 2016}) CREATE (g)-[l:lib {lang: 'java'}]->(j), p=(g) -[:lib {lang: 'c'}]-> (:repo {name: 'agens-graph-odbc', year: 2016}), (g)-[e:doc {lang: 'en'}]->(d) RETURN properties(l) AS lj, properties(j) AS j, properties((edges(p))[0]) AS lc, properties((vertices(p))[1]) AS c, properties(e) AS e, properties(d) AS d; lj | j | lc | c | e | d ------------------+--------------------------------------------+---------------+--------------------------------------------+----------------+-------------------------------------------- {"lang": "java"} | {"name": "agens-graph-jdbc", "year": 2016} | {"lang": "c"} | {"name": "agens-graph-odbc", "year": 2016} | {"lang": "en"} | {"name": "agens-graph-docs", "year": 2016} (1 row) CREATE ()-[a:lib]->(a); ERROR: duplicate variable "a" LINE 1: CREATE ()-[a:lib]->(a); ^ CREATE a=(), (a); ERROR: duplicate variable "a" LINE 1: CREATE a=(), (a); ^ CREATE (a), (a {}); ERROR: duplicate variable "a" LINE 1: CREATE (a), (a {}); ^ CREATE (a), (a); ERROR: there must be at least one relationship LINE 1: CREATE (a), (a); ^ CREATE (=0); ERROR: jsonb object is expected for property map CREATE ()-[]-(); ERROR: only directed relationships are allowed in CREATE CREATE ()-[]->(); ERROR: only one relationship type is allowed for CREATE CREATE ()-[:lib|doc]->(); ERROR: only one relationship type is allowed for CREATE CREATE (a)-[a:lib]->(); ERROR: duplicate variable "a" LINE 1: CREATE (a)-[a:lib]->(); ^ CREATE ()-[a:lib]->()-[a:doc]->(); ERROR: duplicate variable "a" LINE 1: CREATE ()-[a:lib]->()-[a:doc]->(); ^ CREATE a=(), ()-[a:doc]->(); ERROR: duplicate variable "a" LINE 1: CREATE a=(), ()-[a:doc]->(); ^ CREATE ()-[:lib =0]->(); ERROR: jsonb object is expected for property map CREATE (a), a=(); ERROR: duplicate variable "a" LINE 1: CREATE (a), a=(); ^ CREATE ()-[a:lib]->(), a=(); ERROR: duplicate variable "a" LINE 1: CREATE ()-[a:lib]->(), a=(); ^ CREATE a=(), a=(); ERROR: duplicate variable "a" LINE 1: CREATE a=(), a=(); ^ CREATE (:lib); ERROR: label "lib" is edge label LINE 1: CREATE (:lib); ^ CREATE ()-[:repo]->(); ERROR: label "repo" is vertex label LINE 1: CREATE ()-[:repo]->(); ^ CREATE (:ag_vertex); ERROR: specifying default label is not allowed LINE 1: CREATE (:ag_vertex); ^ CREATE ()-[:ag_edge]->(); ERROR: cannot create edge on default label LINE 1: CREATE ()-[:ag_edge]->(); ^ CREATE (=null)-[:lib =null]->(); CREATE TABLE t1 (prop jsonb); CREATE (=(SELECT prop FROM t1))-[:lib =(SELECT prop FROM t1)]->(); MATCH (a) WHERE a.name IS NULL DETACH DELETE a; DROP TABLE t1; CREATE GRAPH g_create; SET GRAPH_PATH = g_create; CREATE ELABEL e1; CREATE p=()-[:e1]->() RETURN p; p -------------------------------------------------------- [ag_vertex[1.1]{},e1[3.1][1.1,1.2]{},ag_vertex[1.2]{}] (1 row) CREATE (a {name:'agens'}), (b {name:a.name}); DROP GRAPH g_create CASCADE; NOTICE: drop cascades to 4 other objects DETAIL: drop cascades to sequence g_create.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to elabel e1 -- -- MATCH -- SET GRAPH_PATH = agens; MATCH (a) RETURN a.name AS a; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) MATCH (a), (a) RETURN a.name AS a; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) CREATE (); MATCH (a:repo) RETURN a.name AS name, a['year'] AS year; name | year --------------------+------ "agens-graph" | 2016 "agens-graph-jdbc" | 2016 "agens-graph-docs" | 2016 "agens-graph-odbc" | 2016 (4 rows) MATCH p=(a)-[b]-(c) RETURN a.name AS a, b.lang AS b, c.name AS c ORDER BY a, b, c; a | b | c --------------------+--------+-------------------- "agens-graph" | "c" | "agens-graph-odbc" "agens-graph" | "en" | "agens-graph-docs" "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-docs" | "en" | "agens-graph" "agens-graph-jdbc" | "java" | "agens-graph" "agens-graph-odbc" | "c" | "agens-graph" (6 rows) MATCH (a)<-[b]-(c)-[d]->(e) RETURN a.name AS a, b.lang AS b, c.name AS c, d.lang AS d, e.name AS e ORDER BY a, b, c, d, e; a | b | c | d | e --------------------+--------+---------------+--------+-------------------- "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" (6 rows) MATCH (a)<-[b]-(c), (c)-[d]->(e) RETURN a.name AS a, b.lang AS b, c.name AS c, d.lang AS d, e.name AS e ORDER BY a, b, c, d, e; a | b | c | d | e --------------------+--------+---------------+--------+-------------------- "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" (6 rows) MATCH (a)<-[b]-(c) MATCH (c)-[d]->(e) RETURN a.name AS a, b.lang AS b, c.name AS c, d.lang AS d, e.name AS e ORDER BY a, b, c, d, e; a | b | c | d | e --------------------+--------+---------------+--------+-------------------- "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-docs" | "en" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-jdbc" | "java" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-odbc" | "c" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" (9 rows) MATCH (a)<-[b]-(c), (f)-[g]->(h), (c)-[d]->(e) RETURN a.name AS a, b.lang AS b, c.name AS c, d.lang AS d, e.name AS e, f.name AS f, g.lang AS g, h.name AS h ORDER BY a, b, c, d, e, f, g, h; a | b | c | d | e | f | g | h --------------------+--------+---------------+--------+--------------------+---------------+--------+-------------------- "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-docs" | "en" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-docs" | "en" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-jdbc" | "java" | "agens-graph" | "c" | "agens-graph-odbc" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-jdbc" | "java" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "en" | "agens-graph-docs" | "agens-graph" | "java" | "agens-graph-jdbc" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "c" | "agens-graph-odbc" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "en" | "agens-graph-docs" "agens-graph-odbc" | "c" | "agens-graph" | "java" | "agens-graph-jdbc" | "agens-graph" | "java" | "agens-graph-jdbc" (18 rows) MATCH (a {name: 'agens-graph'}), (a {year: 2016}) RETURN properties(a) AS a; a --------------------------------------- {"name": "agens-graph", "year": 2016} (1 row) MATCH p=(a)-[]->({name: 'agens-graph-jdbc'}) RETURN a.name AS a; a --------------- "agens-graph" (1 row) MATCH p=()-[:lib]->(a) RETURN a.name AS a; a -------------------- "agens-graph-jdbc" "agens-graph-odbc" (2 rows) MATCH p=()-[{lang: 'en'}]->(a) RETURN a.name AS a; a -------------------- "agens-graph-docs" (1 row) MATCH (a {year: (SELECT to_jsonb(year) FROM history WHERE event = 'Graph')}) WHERE a.name = 'agens-graph' RETURN a.name AS a; a --------------- "agens-graph" (1 row) MATCH (a), (a:repo) RETURN a.name AS a; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) MATCH p=({name: 'agens-graph'})-[{lang: 'java'}]->(m) RETURN *; m | p -----------------------------------------------------+---------------------------------------------------------------------------------------------------------------------------------------- repo[3.2]{"name": "agens-graph-jdbc", "year": 2016} | [repo[3.1]{"name": "agens-graph", "year": 2016},lib[4.1][3.1,3.2]{"lang": "java"},repo[3.2]{"name": "agens-graph-jdbc", "year": 2016}] (1 row) MATCH (); ERROR: Cypher query must end with RETURN or update clause MATCH ()-[a]-(), (a) RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH ()-[a]-(), (a) RETURN *; ^ MATCH a=(), (a) RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH a=(), (a) RETURN *; ^ MATCH (a =0) RETURN *; a --- (0 rows) MATCH ()-[a]-(a) RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH ()-[a]-(a) RETURN *; ^ MATCH ()-[a]-()-[a]-() RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH ()-[a]-()-[a]-() RETURN *; ^ MATCH a=(), ()-[a]-() RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH a=(), ()-[a]-() RETURN *; ^ MATCH p=()-[:lib|doc]->() RETURN *; ERROR: multiple types for relationship not supported MATCH ()-[a =0]-() RETURN *; a --- (0 rows) MATCH (a), a=() RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH (a), a=() RETURN *; ^ MATCH ()-[a]->(), a=() RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH ()-[a]->(), a=() RETURN *; ^ MATCH a=(), a=() RETURN *; ERROR: duplicate variable "a" LINE 1: MATCH a=(), a=() RETURN *; ^ MATCH (:lib) RETURN *; ERROR: label "lib" is edge label LINE 1: MATCH (:lib) RETURN *; ^ MATCH ()-[:repo]->() RETURN *; ERROR: label "repo" is vertex label LINE 1: MATCH ()-[:repo]->() RETURN *; ^ MATCH (a {name: properties.name}) RETURN *; ERROR: variable does not exist LINE 1: MATCH (a {name: properties.name}) RETURN *; ^ MATCH (a) RETURN a.properties; properties ------------ (5 rows) -- MATCH ONLY CREATE VLABEL vl1; CREATE VLABEL vl2 INHERITS(vl1); CREATE VLABEL vl3 INHERITS(vl2); CREATE ELABEL el1; CREATE ELABEL el2 INHERITS(el1); CREATE ELABEL el3 INHERITS(el2); CREATE (:vl1 {id:1}); CREATE (:vl2 {id:2}); CREATE (:vl3 {id:3}); MATCH (A:vl1 {id:1}), (B:vl2 {id:2}) MERGE (A)-[:el1]->(B); MATCH (A:vl1 {id:1}), (C:vl3 {id:3}) MERGE (A)-[:el2]->(C); MATCH (B:vl2 {id:2}), (C:vl3 {id:3}) MERGE (B)-[:el3]->(C); MATCH (N:vl1) RETURN N; n ------------------- vl1[6.1]{"id": 1} vl2[7.1]{"id": 2} vl3[8.1]{"id": 3} (3 rows) MATCH (N:vl2) RETURN N; n ------------------- vl2[7.1]{"id": 2} vl3[8.1]{"id": 3} (2 rows) MATCH (N:vl3) RETURN N; n ------------------- vl3[8.1]{"id": 3} (1 row) MATCH (N:vl1 ONLY) RETURN N; n ------------------- vl1[6.1]{"id": 1} (1 row) MATCH (N:vl2 ONLY) RETURN N; n ------------------- vl2[7.1]{"id": 2} (1 row) MATCH (N ONLY) RETURN N; ERROR: ONLY must have one label preceding it MATCH (A)-[r:el1]->(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 1 | el1[9.1][6.1,7.1]{} | 2 1 | el2[10.1][6.1,8.1]{} | 3 2 | el3[11.1][7.1,8.1]{} | 3 (3 rows) MATCH (A)-[r:el2]->(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 1 | el2[10.1][6.1,8.1]{} | 3 2 | el3[11.1][7.1,8.1]{} | 3 (2 rows) MATCH (A)-[r:el3]->(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 2 | el3[11.1][7.1,8.1]{} | 3 (1 row) MATCH (A)-[r:el1 ONLY]->(B) RETURN A.id, r, B.id; id | r | id ----+---------------------+---- 1 | el1[9.1][6.1,7.1]{} | 2 (1 row) MATCH (A)-[r:el2 ONLY]->(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 1 | el2[10.1][6.1,8.1]{} | 3 (1 row) MATCH (A)-[r ONLY]->(B) RETURN A.id, r, B.id; ERROR: ONLY must have one label preceding it LINE 1: MATCH (A)-[r ONLY]->(B) RETURN A.id, r, B.id; ^ MATCH (A)<-[r:el1]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 2 | el1[9.1][6.1,7.1]{} | 1 3 | el2[10.1][6.1,8.1]{} | 1 3 | el3[11.1][7.1,8.1]{} | 2 (3 rows) MATCH (A)<-[r:el2]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el2[10.1][6.1,8.1]{} | 1 3 | el3[11.1][7.1,8.1]{} | 2 (2 rows) MATCH (A)<-[r:el3]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el3[11.1][7.1,8.1]{} | 2 (1 row) MATCH (A)<-[r:el1 ONLY]-(B) RETURN A.id, r, B.id; id | r | id ----+---------------------+---- 2 | el1[9.1][6.1,7.1]{} | 1 (1 row) MATCH (A)<-[r:el2 ONLY]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el2[10.1][6.1,8.1]{} | 1 (1 row) MATCH (A)-[r:el1]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 2 | el1[9.1][6.1,7.1]{} | 1 3 | el2[10.1][6.1,8.1]{} | 1 1 | el1[9.1][6.1,7.1]{} | 2 3 | el3[11.1][7.1,8.1]{} | 2 1 | el2[10.1][6.1,8.1]{} | 3 2 | el3[11.1][7.1,8.1]{} | 3 (6 rows) MATCH (A)-[r:el2]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el2[10.1][6.1,8.1]{} | 1 3 | el3[11.1][7.1,8.1]{} | 2 1 | el2[10.1][6.1,8.1]{} | 3 2 | el3[11.1][7.1,8.1]{} | 3 (4 rows) MATCH (A)-[r:el3]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el3[11.1][7.1,8.1]{} | 2 2 | el3[11.1][7.1,8.1]{} | 3 (2 rows) MATCH (A)-[r:el1 ONLY]-(B) RETURN A.id, r, B.id; id | r | id ----+---------------------+---- 2 | el1[9.1][6.1,7.1]{} | 1 1 | el1[9.1][6.1,7.1]{} | 2 (2 rows) MATCH (A)-[r:el2 ONLY]-(B) RETURN A.id, r, B.id; id | r | id ----+----------------------+---- 3 | el2[10.1][6.1,8.1]{} | 1 1 | el2[10.1][6.1,8.1]{} | 3 (2 rows) MATCH (A)-[r:el1 *1..3]->(B) RETURN A.id, r, B.id; id | r | id ----+--------------------------------------------+---- 1 | [el1[9.1][6.1,7.1]{}] | 2 1 | [el1[9.1][6.1,7.1]{},el3[11.1][7.1,8.1]{}] | 3 1 | [el2[10.1][6.1,8.1]{}] | 3 2 | [el3[11.1][7.1,8.1]{}] | 3 (4 rows) MATCH (A)-[r:el2 *1..3]->(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 1 | [el2[10.1][6.1,8.1]{}] | 3 2 | [el3[11.1][7.1,8.1]{}] | 3 (2 rows) MATCH (A)-[r:el3 *1..3]->(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 2 | [el3[11.1][7.1,8.1]{}] | 3 (1 row) MATCH (A)-[r:el1 ONLY *1..3]->(B) RETURN A.id, r, B.id; id | r | id ----+-----------------------+---- 1 | [el1[9.1][6.1,7.1]{}] | 2 (1 row) MATCH (A)-[r:el2 ONLY *1..3]->(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 1 | [el2[10.1][6.1,8.1]{}] | 3 (1 row) MATCH (A)<-[r:el1 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+--------------------------------------------+---- 2 | [el1[9.1][6.1,7.1]{}] | 1 3 | [el2[10.1][6.1,8.1]{}] | 1 3 | [el3[11.1][7.1,8.1]{},el1[9.1][6.1,7.1]{}] | 1 3 | [el3[11.1][7.1,8.1]{}] | 2 (4 rows) MATCH (A)<-[r:el2 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 3 | [el2[10.1][6.1,8.1]{}] | 1 3 | [el3[11.1][7.1,8.1]{}] | 2 (2 rows) MATCH (A)<-[r:el3 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 3 | [el3[11.1][7.1,8.1]{}] | 2 (1 row) MATCH (A)<-[r:el1 ONLY *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+-----------------------+---- 2 | [el1[9.1][6.1,7.1]{}] | 1 (1 row) MATCH (A)<-[r:el2 ONLY *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 3 | [el2[10.1][6.1,8.1]{}] | 1 (1 row) MATCH (A)-[r:el1 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+-----------------------------------------------------------------+---- 2 | [el1[9.1][6.1,7.1]{}] | 1 2 | [el3[11.1][7.1,8.1]{},el2[10.1][6.1,8.1]{}] | 1 1 | [el1[9.1][6.1,7.1]{},el3[11.1][7.1,8.1]{},el2[10.1][6.1,8.1]{}] | 1 3 | [el2[10.1][6.1,8.1]{}] | 1 3 | [el3[11.1][7.1,8.1]{},el1[9.1][6.1,7.1]{}] | 1 1 | [el2[10.1][6.1,8.1]{},el3[11.1][7.1,8.1]{},el1[9.1][6.1,7.1]{}] | 1 1 | [el1[9.1][6.1,7.1]{}] | 2 1 | [el2[10.1][6.1,8.1]{},el3[11.1][7.1,8.1]{}] | 2 2 | [el3[11.1][7.1,8.1]{},el2[10.1][6.1,8.1]{},el1[9.1][6.1,7.1]{}] | 2 2 | [el1[9.1][6.1,7.1]{},el2[10.1][6.1,8.1]{},el3[11.1][7.1,8.1]{}] | 2 3 | [el2[10.1][6.1,8.1]{},el1[9.1][6.1,7.1]{}] | 2 3 | [el3[11.1][7.1,8.1]{}] | 2 1 | [el2[10.1][6.1,8.1]{}] | 3 1 | [el1[9.1][6.1,7.1]{},el3[11.1][7.1,8.1]{}] | 3 3 | [el2[10.1][6.1,8.1]{},el1[9.1][6.1,7.1]{},el3[11.1][7.1,8.1]{}] | 3 2 | [el3[11.1][7.1,8.1]{}] | 3 2 | [el1[9.1][6.1,7.1]{},el2[10.1][6.1,8.1]{}] | 3 3 | [el3[11.1][7.1,8.1]{},el1[9.1][6.1,7.1]{},el2[10.1][6.1,8.1]{}] | 3 (18 rows) MATCH (A)-[r:el2 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+---------------------------------------------+---- 2 | [el3[11.1][7.1,8.1]{},el2[10.1][6.1,8.1]{}] | 1 3 | [el2[10.1][6.1,8.1]{}] | 1 1 | [el2[10.1][6.1,8.1]{},el3[11.1][7.1,8.1]{}] | 2 3 | [el3[11.1][7.1,8.1]{}] | 2 1 | [el2[10.1][6.1,8.1]{}] | 3 2 | [el3[11.1][7.1,8.1]{}] | 3 (6 rows) MATCH (A)-[r:el3 *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 3 | [el3[11.1][7.1,8.1]{}] | 2 2 | [el3[11.1][7.1,8.1]{}] | 3 (2 rows) MATCH (A)-[r:el1 ONLY *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+-----------------------+---- 2 | [el1[9.1][6.1,7.1]{}] | 1 1 | [el1[9.1][6.1,7.1]{}] | 2 (2 rows) MATCH (A)-[r:el2 ONLY *1..3]-(B) RETURN A.id, r, B.id; id | r | id ----+------------------------+---- 3 | [el2[10.1][6.1,8.1]{}] | 1 1 | [el2[10.1][6.1,8.1]{}] | 3 (2 rows) MATCH (A:vl1) DETACH DELETE A; MATCH (B:vl2) DETACH DELETE B; MATCH (C:vl3) DETACH DELETE C; -- OPTIONAL MATCH CREATE GRAPH o; SET graph_path = o; CREATE VLABEL person; CREATE ELABEL knows; CREATE (:person {name: 'someone'})-[:knows]->(:person {name: 'somebody'}), (:person {name: 'anybody'})-[:knows]->(:person {name: 'nobody'}); OPTIONAL MATCH (n)-[r]->(p), (m)-[s]->(q) RETURN n.name AS n, type(r) AS r, p.name AS p, m.name AS m, type(s) AS s, q.name AS q ORDER BY n, p, m, q; n | r | p | m | s | q -----------+---------+------------+-----------+---------+------------ "anybody" | "knows" | "nobody" | "anybody" | "knows" | "nobody" "anybody" | "knows" | "nobody" | "someone" | "knows" | "somebody" "someone" | "knows" | "somebody" | "anybody" | "knows" | "nobody" "someone" | "knows" | "somebody" | "someone" | "knows" | "somebody" (4 rows) MATCH (n:person), (m:person) WHERE id(n) <> id(m) OPTIONAL MATCH (n)-[r]->(p), (m)-[s]->(q) RETURN n.name AS n, type(r) AS r, p.name AS p, m.name AS m, type(s) AS s, q.name AS q ORDER BY n, p, m, q; n | r | p | m | s | q ------------+---------+------------+------------+---------+------------ "anybody" | "knows" | "nobody" | "someone" | "knows" | "somebody" "anybody" | | | "nobody" | | "anybody" | | | "somebody" | | "nobody" | | | "anybody" | | "nobody" | | | "somebody" | | "nobody" | | | "someone" | | "somebody" | | | "anybody" | | "somebody" | | | "nobody" | | "somebody" | | | "someone" | | "someone" | "knows" | "somebody" | "anybody" | "knows" | "nobody" "someone" | | | "nobody" | | "someone" | | | "somebody" | | (12 rows) MATCH (n:person), (m:person) WHERE id(n) <> id(m) OPTIONAL MATCH (n)-[r]->(p), (m)-[s]->(q) WHERE m.name = 'someone' RETURN n.name AS n, type(r) AS r, p.name AS p, m.name AS m, type(s) AS s, q.name AS q ORDER BY n, p, m, q; n | r | p | m | s | q ------------+---------+----------+------------+---------+------------ "anybody" | "knows" | "nobody" | "someone" | "knows" | "somebody" "anybody" | | | "nobody" | | "anybody" | | | "somebody" | | "nobody" | | | "anybody" | | "nobody" | | | "somebody" | | "nobody" | | | "someone" | | "somebody" | | | "anybody" | | "somebody" | | | "nobody" | | "somebody" | | | "someone" | | "someone" | | | "anybody" | | "someone" | | | "nobody" | | "someone" | | | "somebody" | | (12 rows) -- Variable Length Relationship CREATE GRAPH t; SET graph_path = t; CREATE VLABEL time; CREATE ELABEL goes; CREATE (:time {sec: 1})-[:goes]-> (:time {sec: 2})-[:goes]-> (:time {sec: 3})-[:goes]-> (:time {sec: 4})-[:goes]-> (:time {sec: 5})-[:goes]-> (:time {sec: 6})-[:goes]-> (:time {sec: 7})-[:goes]-> (:time {sec: 8})-[:goes]-> (:time {sec: 9}); CREATE (:time {sec: 9})-[:goes*1..2]->(:time {sec: 10}); ERROR: variable length relationship is not allowed for CREATE MATCH (a:time)-[x:goes*3]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 3 | 4 2 | 3 | 5 3 | 3 | 6 4 | 3 | 7 5 | 3 | 8 6 | 3 | 9 (6 rows) MATCH (a:time)-[x:goes*0]->(b:time) RETURN a.sec AS a, x, b.sec AS b; a | x | b ---+----+--- 1 | [] | 1 2 | [] | 2 3 | [] | 3 4 | [] | 4 5 | [] | 5 6 | [] | 6 7 | [] | 7 8 | [] | 8 9 | [] | 9 (9 rows) MATCH (a:time)-[x:goes*0..1]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 0 | 1 1 | 1 | 2 2 | 0 | 2 2 | 1 | 3 3 | 0 | 3 3 | 1 | 4 4 | 0 | 4 4 | 1 | 5 5 | 0 | 5 5 | 1 | 6 6 | 0 | 6 6 | 1 | 7 7 | 0 | 7 7 | 1 | 8 8 | 0 | 8 8 | 1 | 9 9 | 0 | 9 (17 rows) MATCH (a:time)-[x:goes*..1]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 1 | 2 2 | 1 | 3 3 | 1 | 4 4 | 1 | 5 5 | 1 | 6 6 | 1 | 7 7 | 1 | 8 8 | 1 | 9 (8 rows) MATCH (a:time)-[x:goes*0..]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 0 | 1 1 | 1 | 2 1 | 2 | 3 1 | 3 | 4 1 | 4 | 5 1 | 5 | 6 1 | 6 | 7 1 | 7 | 8 1 | 8 | 9 2 | 0 | 2 2 | 1 | 3 2 | 2 | 4 2 | 3 | 5 2 | 4 | 6 2 | 5 | 7 2 | 6 | 8 2 | 7 | 9 3 | 0 | 3 3 | 1 | 4 3 | 2 | 5 3 | 3 | 6 3 | 4 | 7 3 | 5 | 8 3 | 6 | 9 4 | 0 | 4 4 | 1 | 5 4 | 2 | 6 4 | 3 | 7 4 | 4 | 8 4 | 5 | 9 5 | 0 | 5 5 | 1 | 6 5 | 2 | 7 5 | 3 | 8 5 | 4 | 9 6 | 0 | 6 6 | 1 | 7 6 | 2 | 8 6 | 3 | 9 7 | 0 | 7 7 | 1 | 8 7 | 2 | 9 8 | 0 | 8 8 | 1 | 9 9 | 0 | 9 (45 rows) MATCH (a:time)-[x:goes*3..6]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 3 | 4 1 | 4 | 5 1 | 5 | 6 1 | 6 | 7 2 | 3 | 5 2 | 4 | 6 2 | 5 | 7 2 | 6 | 8 3 | 3 | 6 3 | 4 | 7 3 | 5 | 8 3 | 6 | 9 4 | 3 | 7 4 | 4 | 8 4 | 5 | 9 5 | 3 | 8 5 | 4 | 9 6 | 3 | 9 (18 rows) MATCH (a:time)-[x:goes*2]->(b:time)-[y:goes]->(c:time)-[z:goes*2]->(d:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b, type(y) AS y, c.sec AS c, length(z) AS z, d.sec AS d; a | x | b | y | c | z | d ---+---+---+--------+---+---+--- 1 | 2 | 3 | "goes" | 4 | 2 | 6 2 | 2 | 4 | "goes" | 5 | 2 | 7 3 | 2 | 5 | "goes" | 6 | 2 | 8 4 | 2 | 6 | "goes" | 7 | 2 | 9 (4 rows) MATCH (a:time)-[x:goes*2]->(b:time) MATCH (b)-[y:goes]->(c:time) MATCH (c)-[z:goes*2]->(d:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b, type(y) AS y, c.sec AS c, length(z) AS z, d.sec AS d; a | x | b | y | c | z | d ---+---+---+--------+---+---+--- 1 | 2 | 3 | "goes" | 4 | 2 | 6 2 | 2 | 4 | "goes" | 5 | 2 | 7 3 | 2 | 5 | "goes" | 6 | 2 | 8 4 | 2 | 6 | "goes" | 7 | 2 | 9 (4 rows) MATCH (d:time)<-[z:goes*2]-(c:time)<-[y:goes]-(b:time)<-[x:goes*2]-(a:time) RETURN d.sec AS d, length(z) AS z, c.sec AS c, type(y) AS y, b.sec AS b, length(x) AS x, a.sec AS a; d | z | c | y | b | x | a ---+---+---+--------+---+---+--- 6 | 2 | 4 | "goes" | 3 | 2 | 1 7 | 2 | 5 | "goes" | 4 | 2 | 2 8 | 2 | 6 | "goes" | 5 | 2 | 3 9 | 2 | 7 | "goes" | 6 | 2 | 4 (4 rows) MATCH (d:time)<-[z:goes*2]-(c:time) MATCH (c)<-[y:goes]-(b:time) MATCH (b)<-[x:goes*2]-(a:time) RETURN d.sec AS d, length(z) AS z, c.sec AS c, type(y) AS y, b.sec AS b, length(x) AS x, a.sec AS a; d | z | c | y | b | x | a ---+---+---+--------+---+---+--- 9 | 2 | 7 | "goes" | 6 | 2 | 4 6 | 2 | 4 | "goes" | 3 | 2 | 1 7 | 2 | 5 | "goes" | 4 | 2 | 2 8 | 2 | 6 | "goes" | 5 | 2 | 3 (4 rows) MATCH (a:time)-[x*0..2]-(b) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ---+---+--- 1 | 0 | 1 1 | 1 | 2 1 | 2 | 3 2 | 1 | 1 2 | 0 | 2 2 | 1 | 3 2 | 2 | 4 3 | 2 | 1 3 | 1 | 2 3 | 0 | 3 3 | 1 | 4 3 | 2 | 5 4 | 2 | 2 4 | 1 | 3 4 | 0 | 4 4 | 1 | 5 4 | 2 | 6 5 | 2 | 3 5 | 1 | 4 5 | 0 | 5 5 | 1 | 6 5 | 2 | 7 6 | 2 | 4 6 | 1 | 5 6 | 0 | 6 6 | 1 | 7 6 | 2 | 8 7 | 2 | 5 7 | 1 | 6 7 | 0 | 7 7 | 1 | 8 7 | 2 | 9 8 | 2 | 6 8 | 1 | 7 8 | 0 | 8 8 | 1 | 9 9 | 2 | 7 9 | 1 | 8 9 | 0 | 9 (39 rows) CREATE (:time {sec: 11})-[:goes {int: 1}]-> (:time {sec: 12})-[:goes {int: 1}]-> (:time {sec: 13})-[:goes {int: 2}]-> (:time {sec: 15})-[:goes {int: 1}]-> (:time {sec: 16})-[:goes {int: 1}]-> (:time {sec: 17}); MATCH (a:time)-[x:goes*1..2 {int: 1}]->(b:time) RETURN a.sec AS a, length(x) AS x, b.sec AS b; a | x | b ----+---+---- 11 | 1 | 12 11 | 2 | 13 12 | 1 | 13 15 | 1 | 16 15 | 2 | 17 16 | 1 | 17 (6 rows) CREATE VLABEL person; CREATE ELABEL knows; -- 1->2->3->4 CREATE (:person {id: 1})-[:knows]-> (:person {id: 2})-[:knows]-> (:person {id: 3})-[:knows]-> (:person {id: 4}); MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+----------------------------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] (2 rows) -- 1->2->3->4 -- `->5 MATCH (a:person {id: 1}) CREATE (a)-[:knows]->(:person {id: 5}); MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+----------------------------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] (3 rows) -- 1<->2->3->4 -- `->5 MATCH (a:person {id: 2}), (b:person {id: 1}) CREATE (a)-[:knows]->(b); MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+----------------------------------------------- 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{}] 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] (4 rows) MATCH (a:person {id: 1})-[x:knows*0..0]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+---- 1 | 1 | [] (1 row) MATCH (a:person {id: 1})-[x:knows*0..1]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+------------------------- 1 | 1 | [] 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] (3 rows) MATCH (a:person {id: 1})-[x:knows*2..2]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+----------------------------------------------- 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] (2 rows) MATCH (a:person {id: 2})-[x:knows*1..1]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+------------------------- 2 | 1 | [knows[6.5][5.2,5.1]{}] 2 | 3 | [knows[6.2][5.2,5.3]{}] (2 rows) MATCH (a:person)-[x:knows*1..1]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] 2 | 1 | [knows[6.5][5.2,5.1]{}] 2 | 3 | [knows[6.2][5.2,5.3]{}] 3 | 4 | [knows[6.3][5.3,5.4]{}] (5 rows) MATCH (a:person)-[x:knows*]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+------------------------------------------------------------------------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{}] 1 | 5 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{},knows[6.4][5.1,5.5]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 4 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.3][5.3,5.4]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] 2 | 1 | [knows[6.5][5.2,5.1]{}] 2 | 2 | [knows[6.5][5.2,5.1]{},knows[6.1][5.1,5.2]{}] 2 | 3 | [knows[6.5][5.2,5.1]{},knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 2 | 4 | [knows[6.5][5.2,5.1]{},knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.3][5.3,5.4]{}] 2 | 5 | [knows[6.5][5.2,5.1]{},knows[6.4][5.1,5.5]{}] 2 | 3 | [knows[6.2][5.2,5.3]{}] 2 | 4 | [knows[6.2][5.2,5.3]{},knows[6.3][5.3,5.4]{}] 3 | 4 | [knows[6.3][5.3,5.4]{}] (14 rows) MATCH (a:person {id: 1})-[x:knows*0..3]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+--------------------------------------------------------------------- 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{}] 1 | 1 | [] 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 4 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.3][5.3,5.4]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] 1 | 5 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{},knows[6.4][5.1,5.5]{}] (7 rows) MATCH (a:person {id: 1})-[x*1..2]-(b:person) RETURN a.id, b.id, x; id | id | x ----+----+----------------------------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.5][5.2,5.1]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] 1 | 2 | [knows[6.5][5.2,5.1]{}] 1 | 3 | [knows[6.5][5.2,5.1]{},knows[6.2][5.2,5.3]{}] 1 | 1 | [knows[6.5][5.2,5.1]{},knows[6.1][5.1,5.2]{}] (7 rows) -- 1->2->3->4 -- `->5 MATCH (a:person {id: 2})-[k:knows]->(b:person {id: 1}) DELETE k; -- +<----+ -- 1->2->3->4 -- `->5 MATCH (a:person {id: 3}), (b:person {id: 1}) CREATE (a)-[:knows]->(b); MATCH (a:person {id: 1})-[x:knows*1..]->(b:person) RETURN a.id, b.id, x; id | id | x ----+----+------------------------------------------------------------------------------------------- 1 | 2 | [knows[6.1][5.1,5.2]{}] 1 | 3 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{}] 1 | 1 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.6][5.3,5.1]{}] 1 | 5 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.6][5.3,5.1]{},knows[6.4][5.1,5.5]{}] 1 | 4 | [knows[6.1][5.1,5.2]{},knows[6.2][5.2,5.3]{},knows[6.3][5.3,5.4]{}] 1 | 5 | [knows[6.4][5.1,5.5]{}] (6 rows) -- 1->2->3->4 -- `->5 MATCH (a:person {id: 3})-[k:knows]->(b:person {id: 1}) DELETE k; MATCH (a:person {id: 1})-[k:knows]->(b:person {id: 5}) DELETE k; CREATE ELABEL friendships INHERITS (knows); MATCH (a:person {id: 1}) CREATE (a)-[:friendships {fromdate: '2014-11-24'}]->(:person {id: 5}); MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN a.id, b.id, x[0].fromdate; id | id | fromdate ----+----+-------------- 1 | 2 | 1 | 3 | 1 | 5 | "2014-11-24" (3 rows) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WHERE x[0].fromdate IS NOT NULL RETURN a.id, b.id, x[0].fromdate; id | id | fromdate ----+----+-------------- 1 | 5 | "2014-11-24" (1 row) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH x[0].fromdate AS fromdate RETURN fromdate; fromdate -------------- "2014-11-24" (3 rows) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH x[0] AS x1 RETURN x1.fromdate, x1; fromdate | x1 --------------+----------------------------------------------------- | knows[6.1][5.1,5.2]{} | knows[6.1][5.1,5.2]{} "2014-11-24" | friendships[7.1][5.1,5.6]{"fromdate": "2014-11-24"} (3 rows) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WHERE x[1].fromdate IS NOT NULL WITH x[0] AS x1, length(x) AS l RETURN x1, l; x1 | l ----+--- (0 rows) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH x[0] AS x1, length(x) AS l RETURN x1, l; x1 | l -----------------------------------------------------+--- knows[6.1][5.1,5.2]{} | 1 knows[6.1][5.1,5.2]{} | 2 friendships[7.1][5.1,5.6]{"fromdate": "2014-11-24"} | 1 (3 rows) MATCH (a:person {id: 1})-[x:knows*1..2]-(b:person) WITH x[0] AS x1, length(x) AS l RETURN x1, l; x1 | l -----------------------------------------------------+--- knows[6.1][5.1,5.2]{} | 1 knows[6.1][5.1,5.2]{} | 2 friendships[7.1][5.1,5.6]{"fromdate": "2014-11-24"} | 1 (3 rows) CREATE ELABEL familyship INHERITS (friendships); MATCH (a:person {id: 5}) CREATE (a)-[:familyship {fromdate: '2015-12-24'}]->(:person {id: 6}); MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH x[0] AS x1, x[1] AS x2, length(x) AS l RETURN x1, x2, l; x1 | x2 | l -----------------------------------------------------+----------------------------------------------------+--- knows[6.1][5.1,5.2]{} | | 1 knows[6.1][5.1,5.2]{} | knows[6.2][5.2,5.3]{} | 2 friendships[7.1][5.1,5.6]{"fromdate": "2014-11-24"} | | 1 friendships[7.1][5.1,5.6]{"fromdate": "2014-11-24"} | familyship[8.2][5.6,5.8]{"fromdate": "2015-12-24"} | 2 (4 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH x[0] AS x1, x[1] AS x2 ORDER BY x2 RETURN x1; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Subquery Scan on _ Output: _.x1 -> Sort Output: (x.edges[1]), (x.edges[2]) Sort Key: (x.edges[2]) -> Nested Loop Output: x.edges[1], x.edges[2] -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (45 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH max(b.id) AS id, x[0] AS x RETURN *; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate Output: max((b.properties.'id'::text)::numeric), (x.edges[1]) Group Key: (x.edges[1]) -> Sort Output: (x.edges[1]), b.properties Sort Key: (x.edges[1]) -> Nested Loop Output: x.edges[1], b.properties -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges, b.properties Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (46 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH DISTINCT x AS path RETURN *; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Unique Output: x.edges -> Sort Output: x.edges Sort Key: x.edges -> Nested Loop Output: x.edges -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (45 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH max(b.id) AS id, x AS x RETURN *; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- GroupAggregate Output: max((b.properties.'id'::text)::numeric), x.edges Group Key: x.edges -> Sort Output: x.edges, b.properties Sort Key: x.edges -> Nested Loop Output: x.edges, b.properties -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges, b.properties Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (46 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WITH max(length(x)) AS x, b.id AS id RETURN *; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- HashAggregate Output: max((length(x.edges))::numeric), (b.properties.'id'::text) Group Key: b.properties.'id'::text -> Nested Loop Output: b.properties.'id'::text, x.edges -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges, b.properties Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (43 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN x, x IS NOT NULL, x[0] IS NULL; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Output: x.edges, (x.edges IS NOT NULL), (x.edges[1] IS NOT DISTINCT FROM NULL) -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (40 rows) EXPLAIN (VERBOSE, COSTS OFF) MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WHERE x[0] IS NOT NULL RETURN x[0]; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Output: x.edges[1] -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" Filter: (x.edges[1] IS DISTINCT FROM NULL) -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) (41 rows) EXPLAIN (VERBOSE, COSTS OFF) SELECT * FROM ( MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) WHERE x[0] IS NOT NULL RETURN x[0] UNION ALL MATCH (a:person {id: 1})-[x:knows*1..2]->(b:person) RETURN x[1] ) AS foo; QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Append -> Nested Loop Output: x.edges[1] -> Seq Scan on t.person a Output: a.id, a.properties Filter: (a.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x.edges Hash Cond: (b.id = x."end") -> Seq Scan on t.person b Output: b.id, b.properties -> Hash Output: x.edges, x."end" -> Subquery Scan on x Output: x.edges, x."end" Filter: (x.edges[1] IS DISTINCT FROM NULL) -> Nested Loop VLE [1..2] Output: knows.start, knows."end", (ARRAY[knows.id]), (ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge]), knows_1."end", knows_1.id, (ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge) -> Result Output: knows.start, knows."end", ARRAY[knows.id], ARRAY[ROW(knows.id, knows.start, knows."end", knows.properties, knows.ctid)::edge] -> Append -> Seq Scan on t.knows Output: knows.start, knows."end", knows.id, knows.properties, knows.ctid Filter: (a.id = knows.start) -> Seq Scan on t.friendships Output: friendships.start, friendships."end", friendships.id, friendships.properties, friendships.ctid Filter: (a.id = friendships.start) -> Index Scan using familyship_start_idx on t.familyship Output: familyship.start, familyship."end", familyship.id, familyship.properties, familyship.ctid Index Cond: (a.id = familyship.start) -> Result Output: knows_1."end", knows_1.id, ROW(knows_1.id, knows_1.start, knows_1."end", knows_1.properties, knows_1.ctid)::edge -> Append -> Seq Scan on t.knows knows_1 Output: knows_1."end", knows_1.id, knows_1.start, knows_1.properties, knows_1.ctid Filter: ($1 = knows_1.start) -> Seq Scan on t.friendships friendships_1 Output: friendships_1."end", friendships_1.id, friendships_1.start, friendships_1.properties, friendships_1.ctid Filter: ($1 = friendships_1.start) -> Index Scan using familyship_start_idx on t.familyship familyship_1 Output: familyship_1."end", familyship_1.id, familyship_1.start, familyship_1.properties, familyship_1.ctid Index Cond: ($1 = familyship_1.start) -> Nested Loop Output: x_1.edges[2] -> Seq Scan on t.person a_1 Output: a_1.id, a_1.properties Filter: (a_1.properties.'id'::text = '1'::jsonb) -> Hash Join Output: x_1.edges Hash Cond: (b_1.id = x_1."end") -> Seq Scan on t.person b_1 Output: b_1.id, b_1.properties -> Hash Output: x_1.edges, x_1."end" -> Subquery Scan on x_1 Output: x_1.edges, x_1."end" -> Nested Loop VLE [1..2] Output: knows_2.start, knows_2."end", (ARRAY[knows_2.id]), (ARRAY[ROW(knows_2.id, knows_2.start, knows_2."end", knows_2.properties, knows_2.ctid)::edge]), knows_3."end", knows_3.id, (ROW(knows_3.id, knows_3.start, knows_3."end", knows_3.properties, knows_3.ctid)::edge) -> Result Output: knows_2.start, knows_2."end", ARRAY[knows_2.id], ARRAY[ROW(knows_2.id, knows_2.start, knows_2."end", knows_2.properties, knows_2.ctid)::edge] -> Append -> Seq Scan on t.knows knows_2 Output: knows_2.start, knows_2."end", knows_2.id, knows_2.properties, knows_2.ctid Filter: (a_1.id = knows_2.start) -> Seq Scan on t.friendships friendships_2 Output: friendships_2.start, friendships_2."end", friendships_2.id, friendships_2.properties, friendships_2.ctid Filter: (a_1.id = friendships_2.start) -> Index Scan using familyship_start_idx on t.familyship familyship_2 Output: familyship_2.start, familyship_2."end", familyship_2.id, familyship_2.properties, familyship_2.ctid Index Cond: (a_1.id = familyship_2.start) -> Result Output: knows_3."end", knows_3.id, ROW(knows_3.id, knows_3.start, knows_3."end", knows_3.properties, knows_3.ctid)::edge -> Append -> Seq Scan on t.knows knows_3 Output: knows_3."end", knows_3.id, knows_3.start, knows_3.properties, knows_3.ctid Filter: ($3 = knows_3.start) -> Seq Scan on t.friendships friendships_3 Output: friendships_3."end", friendships_3.id, friendships_3.start, friendships_3.properties, friendships_3.ctid Filter: ($3 = friendships_3.start) -> Index Scan using familyship_start_idx on t.familyship familyship_3 Output: familyship_3."end", familyship_3.id, familyship_3.start, familyship_3.properties, familyship_3.ctid Index Cond: ($3 = familyship_3.start) (82 rows) -- AG-154, CS-34 : VLE returns incoreect result with sequential scan CREATE GRAPH AG154; SET graph_path = AG154; CREATE ({id:1})-[:rel]->({id:11}); MATCH (a {id:11}) CREATE (a)-[:rel]->({id:111}); MATCH (a {id:111}) CREATE (a)-[:rel]->({id:1111}); MATCH (a {id:111}) CREATE (a)-[:rel]->({id:1112}); MATCH (a {id:111}) CREATE (a)-[:rel]->({id:1113}); MATCH (a {id:11}) CREATE (a)-[:rel]->({id:112}); MATCH (a {id:112}) CREATE (a)-[:rel]->({id:1121}); MATCH (a {id:112}) CREATE (a)-[:rel]->({id:1122}); MATCH (a {id:11}) CREATE (a)-[:rel]->({id:113}); MATCH (a {id:113}) CREATE (a)-[:rel]->({id:1131}); MATCH (a {id:113}) CREATE (a)-[:rel]->({id:1132}); SET enable_indexscan = f; SET enable_seqscan = t; MATCH ({id:1})-[r:rel*]->() RETURN length(r) AS len ORDER BY len; len ----- 1 2 2 2 3 3 3 3 3 3 3 (11 rows) SET enable_indexscan = t; SET enable_seqscan = f; MATCH ({id:1})-[r:rel*]->() RETURN length(r) AS len ORDER BY len; len ----- 1 2 2 2 3 3 3 3 3 3 3 (11 rows) SET enable_indexscan = default; SET enable_seqscan = default; -- shortestpath(), allshortestpaths() SET graph_path = t; CREATE OR REPLACE FUNCTION ids(vertex[]) RETURNS int[] AS $$ DECLARE v vertex; vids int[]; BEGIN IF $1 IS NULL THEN RETURN ARRAY[]::int[]; END IF; FOREACH v IN ARRAY $1 LOOP vids = array_append(vids, (v->>'id')::int); END LOOP; RETURN vids; END; $$ LANGUAGE plpgsql; -- 1->2->3->4->5 MATCH (a:person {id: 1})-[k:knows]->(b:person {id: 5}) DELETE k; MATCH (a:person {id: 5})-[k:knows]->(b:person {id: 6}) DELETE k; MATCH (a:person {id: 6}) DELETE a; MATCH (a:person {id: 4}), (b:person {id: 5}) CREATE (a)-[:knows]->(b); MATCH (p:person), (f:person) WHERE p.id = 3 AND f.id = 4 RETURN ids(nodes(shortestpath((p)-[:knows]->(f)))) AS ids; ids ------- {3,4} (1 row) MATCH (p:person), (f:person) WHERE p.id = 3 AND f.id = 5 RETURN ids(nodes(shortestpath((p)-[:knows]->(f)))) AS ids; ids ----- {} {} (2 rows) MATCH (p:person), (f:person) WHERE p.id = 3 RETURN ids(nodes(shortestpath((p)<-[:knows]-(f)))) AS ids; ids ------- {} {3,2} {} {} {} {} (6 rows) MATCH (p:person), (f:person) WHERE p.id = 3 RETURN ids(nodes(shortestpath((p)-[:knows*]-(f)))) AS ids; ids --------- {3,2,1} {3,2} {} {3,4} {3,4,5} {3,4,5} (6 rows) MATCH (p:person), (f:person), x=shortestpath((p)-[:knows*]-(f)) WHERE p.id = 3 RETURN ids(nodes(x)) AS ids; ids --------- {3,2,1} {3,2} {3,4} {3,4,5} {3,4,5} (5 rows) MATCH x=shortestpath((p:person)-[:knows*]-(f:person)) WHERE p.id = 3 RETURN ids(nodes(x)) AS ids; ids --------- {3,2,1} {3,2} {3,4} {3,4,5} {3,4,5} (5 rows) MATCH (p:person), (f:person) WHERE p.id = 3 RETURN ids(nodes(shortestpath((p)-[:knows*0..1]-(f)))) AS ids; ids ------- {} {3,2} {3} {3,4} {} {} (6 rows) MATCH (p:person), (f:person) WHERE p.id = 1 RETURN ids(nodes(shortestpath((p)-[:knows*2..]->(f)))) AS ids; ERROR: only 0 or 1 is allowed for minimal length LINE 2: RETURN ids(nodes(shortestpath((p)-[:knows*2..]->(f)))) AS id... ^ MATCH (p:person), (f:person) WHERE p.id = 3 AND f.id = 5 CREATE (p)-[:knows]->(:person {id: 6})-[:knows]->(f); MATCH (p:person), (f:person) WHERE p.id = 1 AND f.id = 5 RETURN length(allshortestpaths((p)-[:knows*]-(f))) AS cnt; cnt ----- 2 2 (2 rows) CREATE VLABEL v; CREATE ELABEL e; CREATE (:v {id: 0}); CREATE (:v {id: 1}); CREATE (:v {id: 2}); CREATE (:v {id: 3}); CREATE (:v {id: 4}); CREATE (:v {id: 5}); CREATE (:v {id: 6}); MATCH (v1:v {id: 0}), (v2:v {id: 4}) CREATE (v1)-[:e {weight: 3}]->(v2); MATCH (v1:v {id: 0}), (v2:v {id: 1}) CREATE (v1)-[:e {weight: 7}]->(v2); MATCH (v1:v {id: 0}), (v2:v {id: 5}) CREATE (v1)-[:e {weight: 10}]->(v2); MATCH (v1:v {id: 4}), (v2:v {id: 6}) CREATE (v1)-[:e {weight: 5}]->(v2); MATCH (v1:v {id: 4}), (v2:v {id: 3}) CREATE (v1)-[:e {weight: 11}]->(v2); MATCH (v1:v {id: 4}), (v2:v {id: 1}) CREATE (v1)-[:e {weight: 2}]->(v2); MATCH (v1:v {id: 1}), (v2:v {id: 3}) CREATE (v1)-[:e {weight: 10}]->(v2); MATCH (v1:v {id: 1}), (v2:v {id: 2}) CREATE (v1)-[:e {weight: 4}]->(v2); MATCH (v1:v {id: 1}), (v2:v {id: 5}) CREATE (v1)-[:e {weight: 6}]->(v2); MATCH (v1:v {id: 5}), (v2:v {id: 3}) CREATE (v1)-[:e {weight: 9}]->(v2); MATCH (v1:v {id: 6}), (v2:v {id: 3}) CREATE (v1)-[:e {weight: 4}]->(v2); MATCH (v1:v {id: 2}), (v2:v {id: 3}) CREATE (v1)-[:e {weight: 2}]->(v2); MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1)-[e:e]->(v2), e.weight) RETURN nodes(path); nodes ----------------------------------------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.2]{"id": 1},v[9.3]{"id": 2},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v2)<-[e:e]-(v1), e.weight) RETURN nodes(path); nodes ----------------------------------------------------------------------------------- [v[9.4]{"id": 3},v[9.3]{"id": 2},v[9.2]{"id": 1},v[9.5]{"id": 4},v[9.1]{"id": 0}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1)-[e:e]-(v2), e.weight) RETURN nodes(path); nodes ----------------------------------------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.2]{"id": 1},v[9.3]{"id": 2},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v2)-[e:e]-(v1), e.weight) RETURN nodes(path); nodes ----------------------------------------------------------------------------------- [v[9.4]{"id": 3},v[9.3]{"id": 2},v[9.2]{"id": 1},v[9.5]{"id": 4},v[9.1]{"id": 0}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1)-[e:e]->(v2), e.weight + 1) RETURN nodes(path); nodes ------------------------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.7]{"id": 6},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1)-[e:e]->(v2), e.weight, e.weight >= 5) RETURN nodes(path); nodes --------------------------------------------------- [v[9.1]{"id": 0},v[9.2]{"id": 1},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1)-[e:e]->(v2), e.weight, e.weight) RETURN nodes(path); nodes ----------------------------------------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.2]{"id": 1},v[9.3]{"id": 2},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1:v {id: 0})-[e:e]->(v2), e.weight) RETURN nodes(path); ERROR: property constraint is not supported LINE 2: path=dijkstra((v1:v {id: 0})-[e:e]->(v2), e.weight) ^ MATCH (v1:v {id: 0}), (v2:v {id: 3}), path=dijkstra((v1:v)-[e:e*1..]->(v2), e.weight) RETURN nodes(path); ERROR: variable length relationship is not supported LINE 2: path=dijkstra((v1:v)-[e:e*1..]->(v2), e.weight) ^ MATCH (v1:v {id: 6}), (v2:v {id: 2}), path=dijkstra((v1:v)-[e:e]->(v2), e.weight) RETURN nodes(path); nodes ------- (0 rows) MATCH (v1:v), (v2:v), path=dijkstra((v1:v)-[e:e]->(v2), e.weight) WHERE v1.id = 6 AND v2.id = 2 RETURN nodes(path); nodes ------- (0 rows) MATCH (v1:v {id: 0}), (v2:v {id: 3}) RETURN dijkstra((v1)-[e:e]->(v2), e.weight); ?column? ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"[v[9.1]{\"id\": 0},e[10.1][9.1,9.5]{\"weight\": 3},v[9.5]{\"id\": 4},e[10.6][9.5,9.2]{\"weight\": 2},v[9.2]{\"id\": 1},e[10.8][9.2,9.3]{\"weight\": 4},v[9.3]{\"id\": 2},e[10.12][9.3,9.4]{\"weight\": 2},v[9.4]{\"id\": 3}]"} (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 0}) RETURN dijkstra((v1)-[e:e]->(v2), e.weight); ?column? ------------------------- {"[v[9.1]{\"id\": 0}]"} (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), p=dijkstra((v1)-[:e]->(v2), 1) RETURN nodes(p); nodes --------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.4]{"id": 3}] (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), p=dijkstra((v1)-[:e]->(v2), 1, LIMIT 10) RETURN nodes(p); nodes --------------------------------------------------- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.4]{"id": 3}] [v[9.1]{"id": 0},v[9.6]{"id": 5},v[9.4]{"id": 3}] [v[9.1]{"id": 0},v[9.2]{"id": 1},v[9.4]{"id": 3}] (3 rows) MATCH (:v {id: 4})-[e:e]-(:v {id: 6}) SET e.weight = 4; MATCH (v1:v {id: 0}), (v2:v {id: 3}), (path, x)=dijkstra((v1)-[e:e]->(v2), e.weight, LIMIT 2) RETURN nodes(path), x; nodes | x -----------------------------------------------------------------------------------+---- [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.7]{"id": 6},v[9.4]{"id": 3}] | 11 [v[9.1]{"id": 0},v[9.5]{"id": 4},v[9.2]{"id": 1},v[9.3]{"id": 2},v[9.4]{"id": 3}] | 11 (2 rows) MATCH (v1:v {id: 0}), (v2:v {id: 3}), (path, x)=dijkstra((v2)<-[e:e]->(v1), e.weight, LIMIT 2) RETURN nodes(path), x; nodes | x -----------------------------------------------------------------------------------+---- [v[9.4]{"id": 3},v[9.7]{"id": 6},v[9.5]{"id": 4},v[9.1]{"id": 0}] | 11 [v[9.4]{"id": 3},v[9.3]{"id": 2},v[9.2]{"id": 1},v[9.5]{"id": 4},v[9.1]{"id": 0}] | 11 (2 rows) MATCH (v1:v {id: 0}), (v2:v {id: 3}) RETURN dijkstra((v1)-[e:e]->(v2), e.weight, LIMIT 2); ?column? --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- {"[v[9.1]{\"id\": 0},e[10.1][9.1,9.5]{\"weight\": 3},v[9.5]{\"id\": 4},e[10.4][9.5,9.7]{\"weight\": 4},v[9.7]{\"id\": 6},e[10.11][9.7,9.4]{\"weight\": 4},v[9.4]{\"id\": 3}]","[v[9.1]{\"id\": 0},e[10.1][9.1,9.5]{\"weight\": 3},v[9.5]{\"id\": 4},e[10.6][9.5,9.2]{\"weight\": 2},v[9.2]{\"id\": 1},e[10.8][9.2,9.3]{\"weight\": 4},v[9.3]{\"id\": 2},e[10.12][9.3,9.4]{\"weight\": 2},v[9.4]{\"id\": 3}]"} (1 row) MATCH (v1:v {id: 0}), (v2:v {id: 3}), (path, x)=dijkstra((v1)-[e:e]->(v2), e.weight, LIMIT 0) RETURN nodes(path), x; ERROR: LIMIT must be larger than 0 MATCH (:v {id: 4})-[e:e]-(:v {id: 6}) SET e.weight = -1; MATCH (v1:v {id: 0}), (v2:v {id: 3}), (path, x)=dijkstra((v1)-[e:e]->(v2), e.weight, LIMIT 10) return nodes(path), x; ERROR: WEIGHT must be larger than 0 SET graph_path = agens; -- -- DISTINCT -- MATCH (a:repo)-[]-() RETURN DISTINCT a.name AS a ORDER BY a; a -------------------- "agens-graph" "agens-graph-docs" "agens-graph-jdbc" "agens-graph-odbc" (4 rows) -- -- ORDER BY -- MATCH (a:repo) RETURN a.name AS a ORDER BY a; a -------------------- "agens-graph" "agens-graph-docs" "agens-graph-jdbc" "agens-graph-odbc" (4 rows) MATCH (a:repo) RETURN a.name AS a ORDER BY a ASC; a -------------------- "agens-graph" "agens-graph-docs" "agens-graph-jdbc" "agens-graph-odbc" (4 rows) MATCH (a:repo) RETURN a.name AS a ORDER BY a DESC; a -------------------- "agens-graph-odbc" "agens-graph-jdbc" "agens-graph-docs" "agens-graph" (4 rows) -- -- SKIP and LIMIT -- MATCH (a:repo) RETURN a.name AS a ORDER BY a SKIP 1 LIMIT 1; a -------------------- "agens-graph-docs" (1 row) -- -- WITH -- MATCH (a:repo) WITH a.name AS name RETURN name; name -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) MATCH (a) WITH a WHERE label(a) = 'repo' MATCH p=(a)-[]->(b) RETURN b.name AS b ORDER BY b; b -------------------- "agens-graph-docs" "agens-graph-jdbc" "agens-graph-odbc" (3 rows) MATCH (a) WITH a RETURN b; ERROR: variable does not exist LINE 1: MATCH (a) WITH a RETURN b; ^ MATCH (a) WITH a.name RETURN *; ERROR: expression in WITH must be aliased (use AS) LINE 1: MATCH (a) WITH a.name RETURN *; ^ MATCH () WITH a AS z RETURN a; ERROR: variable does not exist LINE 1: MATCH () WITH a AS z RETURN a; ^ -- -- UNION -- MATCH (a:repo) RETURN a.name AS a UNION ALL MATCH ()-[b:lib]->() RETURN DISTINCT b.lang AS b UNION ALL MATCH ()-[c:doc]->() RETURN DISTINCT c.lang AS c; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" "c" "java" "en" (7 rows) MATCH (a) RETURN a UNION MATCH (b) RETURN b.name; ERROR: UNION types vertex and jsonb cannot be matched -- -- aggregates -- MATCH (a)-[]-(b) RETURN count(a) AS a, b.name AS b ORDER BY a, b; a | b ---+-------------------- 1 | "agens-graph-docs" 1 | "agens-graph-jdbc" 1 | "agens-graph-odbc" 3 | "agens-graph" (4 rows) -- -- EXISTS -- MATCH (a:repo) WHERE exists((a)-[]->()) RETURN a.name AS a; a --------------- "agens-graph" (1 row) -- -- SIZE -- MATCH (a:repo) RETURN a.name AS a, size((a)-[]->()) AS s; a | s --------------------+--- "agens-graph" | 3 "agens-graph-jdbc" | 0 "agens-graph-docs" | 0 "agens-graph-odbc" | 0 (4 rows) -- -- LOAD -- MATCH (a) LOAD FROM history AS a RETURN *; ERROR: duplicate variable "a" CREATE VLABEL feature; CREATE ELABEL supported; MATCH (a:repo {name: 'agens-graph'}) LOAD FROM history AS h CREATE (:feature {name: h.event})-[:supported]->(a); MATCH p=(a)-[:supported]->() RETURN properties(a) AS a ORDER BY a; a ------------------------ {"name": "Graph"} {"name": "PostgreSQL"} (2 rows) -- -- DELETE -- MATCH (a) DELETE a; ERROR: vertices with edges can not be removed MATCH p=()-[:lib]->() DETACH DELETE (vertices(p))[1]; ERROR: only direct variable reference is supported LINE 1: MATCH p=()-[:lib]->() DETACH DELETE (vertices(p))[1]; ^ MATCH (a:repo) RETURN a.name AS a; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) MATCH ()-[a:doc]->() DETACH DELETE end_vertex(a); ERROR: only direct variable reference is supported LINE 1: MATCH ()-[a:doc]->() DETACH DELETE end_vertex(a); ^ MATCH (a:repo) RETURN a.name AS a; a -------------------- "agens-graph" "agens-graph-jdbc" "agens-graph-docs" "agens-graph-odbc" (4 rows) MATCH (a) DETACH DELETE a; MATCH (a) RETURN a; a --- (0 rows) SELECT count(*) FROM agens.ag_edge; count ------- 0 (1 row) -- attempt to delete null object CREATE ({name: 'agensgraph'})-[:made_by]->({name: 'bitnine'}); MATCH (a {name: 'agensgraph'}), (g {name: 'bitnine'}) OPTIONAL MATCH (a)-[r:made_by]-(g) DELETE r; MATCH (a {name: 'agensgraph'}), (g {name: 'bitnine'}) OPTIONAL MATCH (a)-[r:made_by]-(g) DELETE r; NOTICE: skipping deletion of NULL graph element MATCH (a) DETACH DELETE a; -- -- Uniqueness -- CREATE GRAPH u; SET graph_path = u; CREATE ELABEL rel; CREATE (s {id: 1})-[:rel {p: 'a'}]->({id: 2})-[:rel {p: 'b'}]->(s); MATCH (s)-[r1]-(m)-[r2]-(x) RETURN s.id AS s, r1.p AS r1, m.id AS m, r2.p AS r2, x.id AS x ORDER BY s, r1, m, r2, x; s | r1 | m | r2 | x ---+-----+---+-----+--- 1 | "a" | 2 | "b" | 1 1 | "b" | 2 | "a" | 1 2 | "a" | 1 | "b" | 2 2 | "b" | 1 | "a" | 2 (4 rows) -- -- SET/REMOVE -- CREATE GRAPH p; SET graph_path = p; CREATE ELABEL rel; CREATE ({name: 'someone'})-[:rel {k: 'v'}]->({name: 'somebody'}); MATCH (n)-[r]->(m) SET r.l = 'w', n = m, r.k = NULL RETURN properties(n) AS n, properties(r) AS r, properties(m) AS m; n | r | m ----------------------+------------+---------------------- {"name": "somebody"} | {"l": "w"} | {"name": "somebody"} (1 row) MATCH (n)-[r]->(m) REMOVE m.name RETURN properties(n) AS n, properties(r) AS r, properties(m) AS m; n | r | m ----------------------+------------+---- {"name": "somebody"} | {"l": "w"} | {} (1 row) MATCH (n)-[r]->(m) RETURN properties(n) AS n, properties(r) AS r, properties(m) AS m; n | r | m ----------------------+------------+---- {"name": "somebody"} | {"l": "w"} | {} (1 row) MATCH (n) DETACH DELETE (n); -- overwrite (Standard SQL) CREATE ({age: 10}); MATCH (a) SET a.age = 11, a.age = a.age + 1 RETURN properties(a); properties ------------- {"age": 11} (1 row) MATCH (a) RETURN properties(a); properties ------------- {"age": 11} (1 row) MATCH (a) DETACH DELETE (a); -- multiple SET's CREATE ({age: 10}); MATCH (a) SET a.age = 11 SET a.age = a.age + 1 RETURN properties(a); properties ------------- {"age": 12} (1 row) MATCH (a) RETURN properties(a); properties ------------- {"age": 12} (1 row) MATCH (a) DETACH DELETE (a); CREATE ()-[:rel {k: 'v'}]->(); MATCH ()-[r]->() SET r.l = 'x' SET r.l = 'y' RETURN properties(r) AS r; r ---------------------- {"k": "v", "l": "y"} (1 row) MATCH ()-[r]->() RETURN properties(r) AS r; r ---------------------- {"k": "v", "l": "y"} (1 row) MATCH (a) DETACH DELETE (a); CREATE ({age: 1})-[:rel]->({age: 2}); MATCH (a)-[]->(b) SET a.age = a.age + 1, b.age = a.age + b.age RETURN properties(a) AS a, properties(b) AS b; a | b ------------+------------ {"age": 2} | {"age": 3} (1 row) MATCH (a)-[]->(b) RETURN properties(a) AS a, properties(b) AS b; a | b ------------+------------ {"age": 2} | {"age": 3} (1 row) MATCH (a) DETACH DELETE (a); CREATE ({val: 1})-[:rel]->({val: 2}); MATCH (a)-[]->(b) SET a.val = b.val, b.val = a.val; MATCH (a)-[]->(b) RETURN properties(a) AS a, properties(b) AS b; a | b ------------+------------ {"val": 2} | {"val": 1} (1 row) MATCH (a) DETACH DELETE (a); CREATE ({val: 1})-[:rel]->({val: 2}); MATCH (a)-[]->(b) SET a.val = b.val SET b.val = a.val; MATCH (a)-[]->(b) RETURN properties(a) AS a, properties(b) AS b; a | b ------------+------------ {"val": 2} | {"val": 2} (1 row) MATCH (a) DETACH DELETE (a); -- enable_multiple_update SET enable_multiple_update = false; CREATE (:multiple_update {no:1}), (:multiple_update {no:1}); MATCH (a:multiple_update), (b:multiple_update) SET a.no = a.no + 1 RETURN a.no; ERROR: graph element(4,1) has been SET multiple times MATCH (a:multiple_update) RETURN a.no; no ---- 1 1 (2 rows) MATCH (a:multiple_update) SET a.no = 5 SET a.no = 6 SET a.no = 7 SET a.no = 8 RETURN a.no; no ---- 8 8 (2 rows) MATCH (a:multiple_update) RETURN a.no; no ---- 8 8 (2 rows) SET enable_multiple_update = true; MATCH (a:multiple_update), (b:multiple_update) SET a.no = a.no + 1 RETURN a.no; no ---- 10 10 10 10 (4 rows) MATCH (a:multiple_update) RETURN a.no; no ---- 10 10 (2 rows) MATCH (a) DETACH DELETE (a); -- += operator CREATE ({age: 10}); MATCH (a) SET a += {name: 'bitnine', age: 3} RETURN properties(a); properties ------------------------------- {"age": 3, "name": "bitnine"} (1 row) MATCH (a) RETURN properties(a); properties ------------------------------- {"age": 3, "name": "bitnine"} (1 row) MATCH (a) SET a += NULL; ERROR: cannot set property map to NULL LINE 1: MATCH (a) SET a += NULL; ^ HINT: use {} instead of NULL to remove all properties MATCH (a) SET a.name += NULL; ERROR: += operator on a property is not allowed LINE 1: MATCH (a) SET a.name += NULL; ^ MATCH (a) SET a.name += 'someone'; ERROR: += operator on a property is not allowed LINE 1: MATCH (a) SET a.name += 'someone'; ^ MATCH (a) DETACH DELETE (a); -- CREATE ... SET ... CREATE p=(a {no:1})-[r1:rel]->(b {no:2})-[r2:rel]->(c {no:3}) SET a.no = 4, b.no = 5, c.no = 6 SET r1.name = 'agens', r2.name = 'graph' RETURN properties(a), properties(r1), properties(b), properties(r2), properties(c); properties | properties | properties | properties | properties ------------+-------------------+------------+-------------------+------------ {"no": 4} | {"name": "agens"} | {"no": 5} | {"name": "graph"} | {"no": 6} (1 row) MATCH (a)-[r]->(b) RETURN a.no, r.name, b.no; no | name | no ----+---------+---- 4 | "agens" | 5 5 | "graph" | 6 (2 rows) MATCH (a) DETACH DELETE (a); -- remove CREATE ({a: 'a', b: 'b', c: 'c'}); MATCH (a) SET a.a = NULL REMOVE a.b RETURN properties(a); properties ------------ {"c": "c"} (1 row) MATCH (a) RETURN properties(a); properties ------------ {"c": "c"} (1 row) MATCH (a) SET a = NULL; ERROR: cannot set property map to NULL LINE 1: MATCH (a) SET a = NULL; ^ HINT: use {} instead of NULL to remove all properties MATCH (a) DETACH DELETE (a); -- referring to undefined attributes CREATE ({name: 'bitnine'}); CREATE ({age: 10}); MATCH (a) SET a.age = a.age + 1 RETURN properties(a); properties --------------------- {"name": "bitnine"} {"age": 11} (2 rows) MATCH (a) RETURN properties(a); properties --------------------- {"name": "bitnine"} {"age": 11} (2 rows) MATCH (a) SET a.age = 2017 - a.undefined_attr; MATCH (a) RETURN properties(a); properties --------------------- {"name": "bitnine"} {} (2 rows) -- working with NULL CREATE VLABEL person; CREATE (:person {name: 'bitnine', age: NULL}); MATCH (a:person {name: 'bitnine'}) RETURN properties(a) AS a; a --------------------- {"name": "bitnine"} (1 row) MATCH (a:person {age: NULL}) RETURN properties(a) AS a; a --- (0 rows) MATCH (a:person) WHERE a.age IS NULL RETURN properties(a) AS a; a --------------------- {"name": "bitnine"} (1 row) CREATE (:person {name: 'agens', key1: 1, key2: 2, key3: 3}); MATCH (a:person {name: 'agens'}) SET a.key1 = NULL RETURN properties(a); properties ----------------------------------------- {"key2": 2, "key3": 3, "name": "agens"} (1 row) MATCH (a:person {name: 'agens'}) SET a.key2 = null RETURN properties(a); properties ------------------------------ {"key3": 3, "name": "agens"} (1 row) MATCH (a:person {name: 'agens'}) SET a.key3 = {first: 1, last: null} RETURN properties(a); properties ----------------------------------------- {"key3": {"first": 1}, "name": "agens"} (1 row) MATCH (a:person {name: 'agens'}) SET a = {name: 'agens', key4: null} RETURN properties(a); properties ------------------- {"name": "agens"} (1 row) MATCH (a:person {name: 'agens'}) RETURN properties(a); properties ------------------- {"name": "agens"} (1 row) -- -- MERGE -- CREATE GRAPH gm; SET GRAPH_PATH = gm; CREATE VLABEL v1; CREATE VLABEL v2; CREATE ELABEL e1; MERGE (a); MATCH (a) DELETE a; CREATE (:v1 {name: 'foo'}), (:v1 {name: 'bar'}), (:v1 {name: 'foo'}), (:v1 {name: 'bar'}); MATCH (a:v1) MERGE (b:v2 {name: a.name}) ON CREATE SET b.created = true ON MATCH SET b.matched = true; MATCH (a:v2) RETURN properties(a); properties --------------------------------------------------- {"name": "foo", "created": true, "matched": true} {"name": "bar", "created": true, "matched": true} (2 rows) MATCH (a:v1) MERGE (a)-[r:e1 {type: 'same name'}]->(b:v2 {name: a.name}) ON CREATE SET r.created = true, r.matched = null ON MATCH SET r.matched = true, r.created = null; MATCH (a)-[r:e1]->(b) RETURN properties(a), properties(r), properties(b); properties | properties | properties -----------------+----------------------------------------+----------------- {"name": "foo"} | {"type": "same name", "created": true} | {"name": "foo"} {"name": "bar"} | {"type": "same name", "created": true} | {"name": "bar"} {"name": "foo"} | {"type": "same name", "created": true} | {"name": "foo"} {"name": "bar"} | {"type": "same name", "created": true} | {"name": "bar"} (4 rows) MATCH (a:v1) MERGE (a)-[r:e1 {type: 'same name'}]->(b:v2 {name: a.name}) ON CREATE SET r.created = true, r.matched = null ON MATCH SET r.matched = true, r.created = null; MATCH (a)-[r:e1]->(b) RETURN properties(a), properties(r), properties(b); properties | properties | properties -----------------+----------------------------------------+----------------- {"name": "foo"} | {"type": "same name", "matched": true} | {"name": "foo"} {"name": "bar"} | {"type": "same name", "matched": true} | {"name": "bar"} {"name": "foo"} | {"type": "same name", "matched": true} | {"name": "foo"} {"name": "bar"} | {"type": "same name", "matched": true} | {"name": "bar"} (4 rows) MATCH (a:v2) RETURN properties(a); properties --------------------------------------------------- {"name": "foo", "created": true, "matched": true} {"name": "bar", "created": true, "matched": true} {"name": "foo"} {"name": "bar"} {"name": "foo"} {"name": "bar"} (6 rows) MERGE (a:v1)-[r1:e1]->(b:v2) MERGE (a)-[r2:e1]->(b) ON CREATE SET r2.created = true; MATCH p=(a)-[r:e1 {created: true}]->(b) RETURN count(p); count ------- 0 (1 row) CREATE (:v1 {name: 'v1-1'}); MERGE (a:v1 {name: 'v1-1'})-[:e1]->(b:v2 {name: 'v2-1'}); MATCH (a:v1 {name: 'v1-1'})-[r]->(b) RETURN properties(a), properties(b); properties | properties ------------------+------------------ {"name": "v1-1"} | {"name": "v2-1"} (1 row) MATCH (a:v1 {name: 'v1-1'}) RETURN count(a); count ------- 2 (1 row) MATCH (a:v1 {name: 'v1-1'}) DETACH DELETE a; CREATE (:v1 {name: 'v1-1'}); MERGE (a:v1 {name: 'v1-1'}) MERGE (b:v2 {name: 'v2-1'}) MERGE (a)-[:e1]->(b); MATCH (a:v1 {name: 'v1-1'})-[r]->(b) RETURN properties(a), properties(b); properties | properties ------------------+------------------ {"name": "v1-1"} | {"name": "v2-1"} (1 row) MATCH (a:v1 {name: 'v1-1'}) RETURN count(a); count ------- 1 (1 row) MATCH (a:v1 {name: 'v1-1'}) DETACH DELETE a; CREATE VLABEL person; CREATE VLABEL city; CREATE ELABEL hometown; CREATE (:person {name: 'a', bornin: 'seoul'}), (:person {name: 'b', bornin: 'san jose'}), (:person {name: 'c', bornin: 'jeju'}), (:person {name: 'd', bornin: 'san jose'}), (:person {name: 'e', bornin: 'seoul'}), (:person {name: 'f', bornin: 'los angeles'}); MATCH (a:person) MERGE (b:city {name: a.bornin}) ON CREATE SET b.population = 1 ON MATCH SET b.population = b.population + 1; MATCH (c:city) RETURN c.name, c.population ORDER BY name; name | population ---------------+------------ "jeju" | 1 "los angeles" | 1 "san jose" | 2 "seoul" | 2 (4 rows) MATCH (a:person) MERGE (a)-[:hometown]->(b:city {name: a.bornin}); MATCH (:city)<-[r]-(:person) RETURN count(r); count ------- 6 (1 row) MATCH (a:city) DETACH DELETE a; CREATE CONSTRAINT ON city ASSERT name IS UNIQUE; MATCH (a:person) MERGE (a)-[:hometown]->(b:city {name: a.bornin}); ERROR: conflicting key value violates exclusion constraint "city_unique_constraint" DETAIL: Key ((properties.'name'::text))=("san jose") conflicts with existing key ((properties.'name'::text))=("san jose"). MATCH (a:city) DETACH DELETE a; -- unspecified direction CREATE (a {id: 2}), (b {id: 1}); MATCH (a {id: 2}), (b {id: 1}) MERGE (a)-[r:e1]-(b) RETURN properties(startnode(r)) as s, properties(endnode(r)) as e; s | e -----------+----------- {"id": 2} | {"id": 1} (1 row) MATCH (a {id: 1}), (b {id: 2}) MERGE (a)-[r:e1]-(b) RETURN properties(a), properties(b); properties | properties ------------+------------ {"id": 1} | {"id": 2} (1 row) MATCH (a) DETACH DELETE a; CREATE (a {id: 2}), (b {id: 1}), (c {id: 1}), (d {id: 2}) CREATE (a)-[:e1 {name: 'ab'}]->(b) CREATE (c)-[:e1 {name: 'cd'}]->(d); MATCH (a {id: 2})-[]-(b {id: 1}) MERGE (a)-[r:e1]-(b) RETURN properties(r); properties ---------------- {"name": "ab"} {"name": "cd"} (2 rows) MATCH (a) DETACH DELETE a; -- update clauses CREATE (a:v1 {name: 'bitnine'}) MERGE (:v2 {name: a.name}); CREATE (a:v1 {name: 'AgensGraph'}) MERGE (b:v2 {name: a.name}) RETURN properties(a), properties(b); properties | properties ------------------------+------------------------ {"name": "AgensGraph"} | {"name": "AgensGraph"} (1 row) MERGE (a:v1 {name: 'bitnine'}) MERGE (b:v1 {name: 'AgensGraph'}) CREATE p=(a)-[r:e1 {name: a.name + b.name}]->(b) RETURN properties(a), properties(r), properties(b), count(p); properties | properties | properties | count ---------------------+-------------------------------+------------------------+------- {"name": "bitnine"} | {"name": "bitnineAgensGraph"} | {"name": "AgensGraph"} | 1 (1 row) MERGE (a {name: 'bitnine'}) CREATE (b:v1 {name: a.name}) MERGE (c:v1 {name: 'bitnine'}) ON MATCH SET c.matched = true ON CREATE SET c.matched = false; MATCH (a) RETURN properties(a); properties -------------------------------------- {"name": "AgensGraph"} {"name": "bitnine", "matched": true} {"name": "bitnine", "matched": true} {"name": "bitnine", "matched": true} {"name": "bitnine"} {"name": "AgensGraph"} (6 rows) MATCH (a) DETACH DELETE a; -- wrong case MERGE (a:v1) MERGE (b:v2 {name: a.notexistent}); MERGE (a:v1) ON MATCH SET a.matched = true MERGE (b:v2 {name: a.name}); ERROR: ON CREATE/MATCH SET between MERGE clauses is not allowed MERGE (a:v1) MATCH (b:v2 {name: a.name}) RETURN a, b; ERROR: Cypher read clauses cannot follow update clauses MERGE (a:v1) MERGE (b:v2 {name: a.name}) MERGE (a); ERROR: duplicate variable "a" LINE 1: MERGE (a:v1) MERGE (b:v2 {name: a.name}) MERGE (a); ^ MERGE (a)-[r]->(b); ERROR: only one relationship type is allowed for MERGE MERGE (a)-[r:e1]->(b) MERGE (a); ERROR: duplicate variable "a" LINE 1: MERGE (a)-[r:e1]->(b) MERGE (a); ^ MERGE (a)-[r:e1]->(b) MERGE (a)-[r:e1]->(b); ERROR: duplicate variable "r" LINE 1: MERGE (a)-[r:e1]->(b) MERGE (a)-[r:e1]->(b); ^ MERGE (a)-[:e1]->(a:v1); ERROR: duplicate variable "a" LINE 1: MERGE (a)-[:e1]->(a:v1); ^ MERGE (=10); ERROR: jsonb object is expected for property map MERGE ()-[:e1 =10]->(); ERROR: jsonb object is expected for property map MERGE (:ag_vertex); ERROR: specifying default label is not allowed LINE 1: MERGE (:ag_vertex); ^ MERGE ()-[:ag_edge]->(); ERROR: cannot create edge on default label LINE 1: MERGE ()-[:ag_edge]->(); ^ DROP GRAPH gm CASCADE; NOTICE: drop cascades to 9 other objects DETAIL: drop cascades to sequence gm.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to vlabel v1 drop cascades to vlabel v2 drop cascades to elabel e1 drop cascades to vlabel person drop cascades to vlabel city drop cascades to elabel hometown -- -- null properties -- CREATE GRAPH np; SET GRAPH_PATH = np; SHOW allow_null_properties; allow_null_properties ----------------------- off (1 row) SET allow_null_properties = off; CREATE (:v {z: null}); CREATE (:v {z: (SELECT 'null'::jsonb)}); CREATE (:v {z: {z: null}}); CREATE (:v {z: (SELECT '{"z": null}'::jsonb)}); CREATE (n:v {p: 0}) SET n.z = null, n.p = null; CREATE (n:v) SET n.z = (SELECT 'null'::jsonb); CREATE (n:v) SET n.z = {z: null}; CREATE (n:v) SET n.z = (SELECT '{"z": null}'::jsonb); MATCH (n:v) RETURN n; n ----------------- v[3.1]{} v[3.2]{} v[3.3]{"z": {}} v[3.4]{"z": {}} v[3.5]{} v[3.6]{} v[3.7]{"z": {}} v[3.8]{"z": {}} (8 rows) CREATE (n:v {z: 0}) SET n.z = null; CREATE (n:v {z: 0}) SET n.z = (SELECT 'null'::jsonb); CREATE (n:v {z: 0}) REMOVE n.z; MATCH (n:v) RETURN n; n ----------------- v[3.1]{} v[3.2]{} v[3.3]{"z": {}} v[3.4]{"z": {}} v[3.5]{} v[3.6]{} v[3.7]{"z": {}} v[3.8]{"z": {}} v[3.9]{} v[3.10]{} v[3.11]{} (11 rows) SET allow_null_properties = on; CREATE (:w {z: null}); CREATE (:w {z: (SELECT 'null'::jsonb)}); CREATE (:w {z: {z: null}}); CREATE (:w {z: (SELECT '{"z": null}'::jsonb)}); CREATE (n:w {p: 0}) SET n.z = null, n.p = null; CREATE (n:w) SET n.z = (SELECT 'null'::jsonb); CREATE (n:w) SET n.z = {z: null}; CREATE (n:w) SET n.z = (SELECT '{"z": null}'::jsonb); MATCH (n:w) RETURN n; n ------------------------------ w[4.1]{"z": null} w[4.2]{"z": null} w[4.3]{"z": {"z": null}} w[4.4]{"z": {"z": null}} w[4.5]{"p": null, "z": null} w[4.6]{"z": null} w[4.7]{"z": {"z": null}} w[4.8]{"z": {"z": null}} (8 rows) CREATE (n:w {z: 0}) SET n.z = null; CREATE (n:w {z: 0}) SET n.z = (SELECT 'null'::jsonb); CREATE (n:w {z: 0}) REMOVE n.z; MATCH (n:w) RETURN n; n ------------------------------ w[4.1]{"z": null} w[4.2]{"z": null} w[4.3]{"z": {"z": null}} w[4.4]{"z": {"z": null}} w[4.5]{"p": null, "z": null} w[4.6]{"z": null} w[4.7]{"z": {"z": null}} w[4.8]{"z": {"z": null}} w[4.9]{"z": null} w[4.10]{"z": null} w[4.11]{} (11 rows) SET allow_null_properties = off; -- -- String Matching -- -- starts with RETURN 'abc' STARTS WITH 'a'; string_starts_with -------------------- t (1 row) RETURN 'abc' STARTS WITH ''; string_starts_with -------------------- t (1 row) RETURN 'abc' STARTS WITH 'bc'; string_starts_with -------------------- f (1 row) RETURN 'abc' STARTS WITH 'abcd'; string_starts_with -------------------- f (1 row) RETURN 'abc' STARTS WITH 1; ERROR: STARTS WITH: two string values expected but "abc", 1 RETURN ['abc' STARTS WITH 'a']; ?column? ---------- [true] (1 row) -- ends with RETURN 'abc' ENDS WITH 'c'; string_ends_with ------------------ t (1 row) RETURN 'abc' ENDS WITH ''; string_ends_with ------------------ t (1 row) RETURN 'abc' ENDS WITH 'ab'; string_ends_with ------------------ f (1 row) RETURN 'abc' ENDS WITH 'abcd'; string_ends_with ------------------ f (1 row) RETURN 'abc' ENDS WITH 1; ERROR: ENDS WITH: two string values expected but "abc", 1 RETURN ['abc' ENDS WITH 'c']; ?column? ---------- [true] (1 row) -- contains RETURN 'abc' CONTAINS 'b'; string_contains ----------------- t (1 row) RETURN 'abc' CONTAINS ''; string_contains ----------------- t (1 row) RETURN 'abc' CONTAINS 'abcd'; string_contains ----------------- f (1 row) RETURN 'abc' CONTAINS 1; ERROR: CONTAINS: two string values expected but "abc", 1 RETURN ['abc' CONTAINS 'b']; ?column? ---------- [true] (1 row) -- =~ RETURN 'abc' =~ 'abc'; string_regex -------------- t (1 row) RETURN 'abc' =~ ''; string_regex -------------- t (1 row) RETURN 'abc' =~ 'a'; string_regex -------------- t (1 row) RETURN 'abc' =~ 'abcd'; string_regex -------------- f (1 row) RETURN 'abc' =~ '(?i)A'; string_regex -------------- t (1 row) RETURN 'abc' =~ 'a(b{1})c'; string_regex -------------- t (1 row) RETURN 'abc' =~ 1; ERROR: Regular Expression Pattern: two string values expected but "abc", 1 RETURN ['abc' =~ 'abc']; ?column? ---------- [true] (1 row) -- -- graphid comparison -- CREATE GRAPH gid; SET GRAPH_PATH = gid; CREATE (); CREATE (); MATCH (n) WHERE id(n) = '1.1' RETURN n; n ------------------ ag_vertex[1.1]{} (1 row) MATCH (n) WHERE id(n) > 1.1 RETURN n; n ------------------ ag_vertex[1.2]{} (1 row) MATCH (n) WHERE id(n) < '1.2' RETURN n; n ------------------ ag_vertex[1.1]{} (1 row) MATCH (n) WHERE id(n) >= 1.1 RETURN n; n ------------------ ag_vertex[1.1]{} ag_vertex[1.2]{} (2 rows) MATCH (n) WHERE id(n) <= 1.2 RETURN n; n ------------------ ag_vertex[1.1]{} ag_vertex[1.2]{} (2 rows) MATCH (n) WHERE id(n) <> 1.1 RETURN n; n ------------------ ag_vertex[1.2]{} (1 row) -- -- implicit load -- CREATE GRAPH impload; SET GRAPH_PATH = impload; CREATE TABLE external_table (id int, name varchar(255)); INSERT INTO external_table VALUES (1, '1'); LOAD FROM external_table AS r CREATE (=r); MATCH (n) RETURN n; n -------------------------------------- ag_vertex[1.1]{"id": 1, "name": "1"} (1 row) -- cleanup DROP GRAPH impload CASCADE; NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to sequence impload.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge DROP GRAPH gid CASCADE; NOTICE: drop cascades to 3 other objects DETAIL: drop cascades to sequence gid.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge DROP GRAPH np CASCADE; NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to sequence np.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to vlabel v drop cascades to vlabel w DROP GRAPH p CASCADE; NOTICE: drop cascades to 6 other objects DETAIL: drop cascades to sequence p.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to elabel rel drop cascades to vlabel multiple_update drop cascades to vlabel person DROP GRAPH u CASCADE; NOTICE: drop cascades to 4 other objects DETAIL: drop cascades to sequence u.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to elabel rel DROP GRAPH t CASCADE; NOTICE: drop cascades to 11 other objects DETAIL: drop cascades to sequence t.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to vlabel time drop cascades to elabel goes drop cascades to vlabel person drop cascades to elabel knows drop cascades to elabel friendships drop cascades to elabel familyship drop cascades to vlabel v drop cascades to elabel e DROP GRAPH o CASCADE; NOTICE: drop cascades to 5 other objects DETAIL: drop cascades to sequence o.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to vlabel person drop cascades to elabel knows DROP GRAPH AG154 CASCADE; NOTICE: drop cascades to 4 other objects DETAIL: drop cascades to sequence ag154.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to elabel rel SET graph_path = agens; DROP VLABEL feature; DROP ELABEL supported; DROP VLABEL repo; DROP ELABEL lib; DROP ELABEL doc; DROP GRAPH agens CASCADE; NOTICE: drop cascades to 10 other objects DETAIL: drop cascades to sequence agens.ag_label_seq drop cascades to vlabel ag_vertex drop cascades to elabel ag_edge drop cascades to vlabel vl1 drop cascades to vlabel vl2 drop cascades to vlabel vl3 drop cascades to elabel el1 drop cascades to elabel el2 drop cascades to elabel el3 drop cascades to elabel made_by DROP TABLE history;