Coming from Cypher¶
Grafeo runs openCypher and ISO GQL on the same database, and most Cypher queries read much the same in GQL. This page lists the places where the same query gives other rows in GQL, or where GQL writes it another way.
Path Mode¶
A variable-length pattern in GQL matches walks by default (WALK): a walk may use an edge more than once, so it can go back along the edge it came in on. openCypher uses each relationship at most once in a pattern, as a trail. On a graph with one edge, Alix KNOWS Gus:
Write MATCH TRAIL ... to get Cypher's rows. See Path Modes for ACYCLIC and SIMPLE.
Numbers With a Point¶
In GQL a number with a point is an exact DECIMAL; in Cypher it is a float:
A decimal compares with a float by value, so WHERE n.score > 0.77 keeps the same rows of a float property in both languages. For a float in GQL, write an exponent (0.77e0) or the suffix F (0.77F), or pass the value as a parameter. See Exact and Approximate Numbers.
Quantifiers¶
ISO GQL writes the repetition after the edge: -[:KNOWS]->{1,3} for Cypher's -[:KNOWS*1..3]->, and -[:KNOWS]->{1,} for -[:KNOWS*]->.
Grafeo's GQL also takes the Cypher form -[:KNOWS*1..3]->, but only the ISO form runs in other GQL engines.
WITH, UNWIND and LET¶
ISO GQL has no WITH: bind a value with LET, and keep rows with FILTER or a WHERE after a MATCH. Cypher's UNWIND list AS x is FOR x IN list.
Grafeo's GQL also takes WITH, UNWIND, MERGE and list comprehensions ([x IN list WHERE x > 1 | x * 2]), so a Cypher query that uses them often runs as it is. These are not ISO GQL, and other GQL engines may refuse them. EXISTS { ... } is ISO GQL.
A GQL query cannot start with WITH: write a leading WITH 'Alix' AS name as LET name = 'Alix'.
Map Projection¶
Cypher's map projection n {.name, .age} is a map literal in GQL, {name: n.name, age: n.age}. A missing property is a null value in both.
Comments¶
A line comment starts with // in both languages, and a block comment is /* ... */, so Cypher comments move to GQL as they are. GQL also reads -- and a space as a line comment (-- without one is an undirected edge); Cypher has no such comment, so keep // in a query that must run in both.
// People in Amsterdam
MATCH (p:Person {city: 'Amsterdam'}) /* any age */
RETURN p.name -- one row per person
Reserved Words as Names¶
GQL reserves more words than openCypher, among them LIKE and EXISTS, so they cannot stand as a variable or an alias as they are. LIKE is a common one: a Cypher variable like must be renamed or quoted as `like` in GQL. Rename such a name, or quote it in backticks; the error for a reserved word names it and says to quote it. After AS and as a LET or FOR variable a double-quoted name works too (RETURN 1 AS "two words"); in an expression a double-quoted sequence is a string, so read such a name back with backticks:
sum() of No Values¶
sum() over no rows, or over only nulls, is 0 in Cypher, as openCypher defines it, and NULL in GQL, as in SQL:
Zoned and Local Datetimes¶
GQL compares a zoned datetime with a local one by reading the local value at the session time zone (UTC when the session sets none, see SESSION SET TIME ZONE). openCypher keeps them apart: = between them is false and < is null. Two zoned datetimes compare by their instant in both languages.