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:
- 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" │
└─────────────────────────┘