Comparison Between Cypher and nGQL

Conceptual Comparisons

Name Cypher nGQL
vertex, node node vertex
edge, relationship relationship edge
vertex type label tag
edge type relationship type edge type
vertex identifier node id generated by default vid
edge identifier edge id generated by default src, dst, rank

Basic Graph Operations

Operations Cypher nGQL
List all labels/tags MATCH (n) RETURN distinct labels(n);
call db.labels();
SHOW TAGS
Insert a vertex with a specified type CREATE (:Person {age: 16}) INSERT VERTEX <tag_name> (prop_name_list) VALUES <vid>:(prop_value_list)
Insert an edge with specified edge type CREATE (src)-[rel:LIKES]->(dst)
SET rel.prop = V
INSERT EDGE <edge_type> ( prop_name_list ) VALUES <src_vid> -> <dst_vid>[@<rank>]: ( prop_value_list )
Delete a vertex MATCH (n) WHERE ID(n) = vid
DETACH DELETE n
DELETE VERTEX <vid>
Delete an edge MATCH ()-[r]->() WHERE ID(r)=edgeID
DELETE r
DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>]
Update a vertex property SET n.name = V UPDATE VERTEX <vid> SET <update_columns>
Fetch vertex prop MATCH (n)
WHERE ID(n) = vid
RETURN properties(n)
FETCH PROP ON <tag_name> <vid>
Fetch edge prop MATCH (n)-[r]->()
WHERE ID(r)=edgeID
return properties(r)
FETCH PROP ON <edge_type> <src_vid> -> <dst_vid>[@<rank>]
Query a vertex along specified edge type MATCH (n)-[r:edge_type]->() WHERE ID(n) = vid GO FROM <vid> OVER <edge_type>
Query a vertex along specified edge type reversely MATCH (n)<-[r:edge_type]-() WHERE ID(n) = vid GO FROM <vid> OVER <edge_type> REVERSELY
Get the N-Hop along a specified edge type MATCH (n)-[r:edge_type*N]->()
WHERE ID(n) = vid
return r
GO N STEPS FROM <vid> OVER <edge_type>
Find path between two vertices MATCH p =(a)-[]->(b)
WHERE ID(a) = a_vid AND ID(b) = b_vid
RETURN p
FIND ALL PATH FROM <a_vid> TO <b_vid> OVER *

Example Queries

The example queries are based on the graph below:

image

  • Insert data
# insert vertex
nebula> INSERT VERTEX character(name, age, type) VALUES hash("saturn"):("saturn", 10000, "titan"), hash("jupiter"):("jupiter", 5000, "god");

# insert edge
nebula> INSERT EDGE father() VALUES hash("jupiter")->hash("saturn"):();

// cypher
cypher> CREATE (src:character {name:"saturn", age: 10000, type:"titan"})
      > CREATE (dst:character {name:"jupiter", age: 5000, type:"god"})
      > CREATE (src)-[rel:father]->(dst)
 ```

- Delete vertex

```ngql
nebula> DELETE VERTEX hash("prometheus");

cypher> MATCH (n:character {name:"prometheus"})
        > DETACH DELETE n
  • Update vertex
nebula> UPDATE VERTEX hash("jesus") SET character.type = 'titan';

cypher> MATCH (n:character {name:"jesus"})
      > SET n.type = 'titan'
  • Fetch vertices properties
nebula> FETCH PROP ON character hash("saturn");
  ===================================================
  | character.name | character.age | character.type |
  ===================================================
  | saturn         | 10000         | titan          |
  ---------------------------------------------------

cypher> MATCH (n:character {name:"saturn"})
      > RETURN properties(n)
  ╒════════════════════════════════════════════╕
  │"properties(n)"                             │
  ╞════════════════════════════════════════════╡
  │{"name":"saturn","type":"titan","age":10000}│
  └────────────────────────────────────────────┘
  • Find the name of hercules's grandfather
nebula> GO 2 STEPS FROM hash("hercules") OVER father YIELD  $$.character.name;
    =====================
    | $$.character.name |
    =====================
    | saturn            |
    ---------------------

cypher> MATCH (src:character{name:"hercules"})-[r:father*2]->(dst:character)
      > RETURN dst.name
      ╒══════════╕
      │"dst.name"│
      ╞══════════╡
      │"satun"   │
      └──────────┘
  • Find the name of hercules's father
nebula> GO FROM hash("hercules") OVER father YIELD $$.character.name;
    =====================
    | $$.character.name |
    =====================
    | jupiter           |
    ---------------------

cypher> MATCH (src:character{name:"hercules"})-[r:father]->(dst:character)
      > RETURN dst.name
      ╒══════════╕
      │"dst.name"│
      ╞══════════╡
      │"jupiter" │
      └──────────┘
  • Find the the centenarians' name.
nebula> # coming soon

cypher> MATCH (src:character)
      > WHERE src.age > 100
      > RETURN src.name
      ╒═══════════╕
      │"src.name" │
      ╞═══════════╡
      │  "saturn" │
      ├───────────┤
      │ "jupiter" │
      ├───────────┤
      │ "neptune" │
      │───────────│
      │  "pluto"  │
      └───────────┘
  • Find who live with pluto
nebula> GO FROM hash("pluto") OVER lives YIELD lives._dst AS place | GO FROM $-.place OVER lives REVERSELY WHERE \
      > $$.character.name != "pluto" YIELD $$.character.name AS cohabitants;
    ===============
    | cohabitants |
    ===============
    | cerberus    |
    ---------------

cypher> MATCH (src:character{name:"pluto"})-[r1:lives]->()<-[r2:lives]-(dst:character)
      > RETURN dst.name
      ╒══════════╕
      │"dst.name"│
      ╞══════════╡
      │"cerberus"│
      └──────────┘
  • Find pluto's brother and their habitations?
nebula> GO FROM hash("pluto") OVER brother YIELD brother._dst AS god | \
      > GO FROM $-.god OVER lives YIELD $^.character.name AS Brother, $$.location.name AS Habitations;
    =========================
    | Brother | Habitations |
    =========================
    | jupiter | sky         |
    -------------------------
    | neptune | sea         |
    -------------------------

cypher> MATCH (src:Character{name:"pluto"})-[r1:brother]->(bro:Character)-[r2:lives]->(dst)
      > RETURN bro.name, dst.name
      ╒═════════════════════════╕
      │"bro.name"    │"dst.name"│
      ╞═════════════════════════╡
      │ "jupiter"    │  "sky"   │
      ├─────────────────────────┤
      │ "neptune"    │ "sea"    │
      └─────────────────────────┘