Skip to content

Comparison Between Gremlin and nGQL

Introduction to Gremlin

Gremlin is a graph traversal language developed by Apache TinkerPop. It can be either declarative or imperative. Gremlin is Groovy-based, but has many language variants that allow developers to write Gremlin queries natively in many modern programming languages such as Java, JavaScript, Python, Scala, Clojure and Groovy.

Introduction to nGQL

Nebula Graph introduces its own query language, nGQL, which is a declarative, textual query language like SQL, but for graphs. Unlike SQL, nGQL is all about expressing graph patterns. The features of nGQL are as follows:

  • Syntax is close to SQL, but not exactly the same (Easy to learn)
  • Expandable
  • Keyword is case insensitive
  • Support basic graph traverse
  • Support pattern matching
  • Support aggregation
  • Support graph mutation
  • Support distributed transaction (future release)
  • Statement composition, but NO statement embedding (Easy to read)

Conceptual Comparisons

Name Gremlin nGQL
vertex, node vertex vertex
edge, relationship edge edge
vertex type label tag
edge type label edge type
vertex id vid vid
edge id eid not support

In Gremlin and nGQL, vertices and edges are identified with unique identifiers. In Nebula Graph, you can either specify identifiers or generate automatically with the hash or uuid function.

Basic Graph Operations

Name Gremlin nGQL
Create a new graph g = TinkerGraph.open().traversal() CREATE SPACE gods
Show vertices' types g.V().label() SHOW TAGS
Insert a vertex with a specified type g.addV(String vertexLabel).property() INSERT VERTEX (prop_name_list) VALUES \:(prop_value_list)
Insert an edge with specified edge type g.addE(String edgeLabel).from(v1).to(v2).property() INSERT EDGE ( ) VALUES -> : ( )
Delete a vertex g.V(\).drop() DELETE VERTEX \
Delete an edge g.E(\).outE(\).where(otherV().is(\))drop() DELETE EDGE \ -> \
Update a vertex property g.V(\).property() UPDATE VERTEX \ SET
Fetch vertices with ID g.V(\) FETCH PROP ON \
Fetch edges with ID g.E( >> ) FETCH PROP ON ->
Query a vertex along specified edge type g.V(\).outE( \) GO FROM \ OVER \
Query a vertex along specified edge type reversely g.V(\).in( \) GO FROM \ OVER \ REVERSELY
Query N hops along a specified edge g.V(\).repeat(out(\)).times(N) GO N STEPS FROM \ OVER \
Find path between two vertices g.V(\).repeat(out()).until(\).path() FIND ALL PATH FROM \ TO \ OVER *

Example Queries

The examples in this section make extensive use of the toy graph distributed with Janus Graph called The Graphs of Gods. This graph is diagrammed below. The abstract data model is known as a Property Graph Model and this particular instance describes the relationships between the beings and places of the Roman pantheon.

image

  • Insert data

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

gremlin> saturn = g.addV("character").property(T.id, 1).property('name', 'saturn').property('age', 10000).property('type', 'titan').next(); ==>v[1] gremlin> jupiter = g.addV("character").property(T.id, 2).property('name', 'jupiter').property('age', 5000).property('type', 'god').next(); ==>v[2] gremlin> prometheus = g.addV("character").property(T.id, 31).property('name', 'prometheus').property('age', 1000).property('type', 'god').next(); ==>v[31] gremlin> jesus = g.addV("character").property(T.id, 32).property('name', 'jesus').property('age', 5000).property('type', 'god').next(); ==>v[32]

# insert edge nebula> INSERT EDGE father() VALUES hash("jupiter")->hash("saturn"):(); gremlin> g.addE("father").from(jupiter).to(saturn).property(T.id, 13); ==>e[13][2-father->1] ```

  • Delete vertex

bash nebula> DELETE VERTEX hash("prometheus"); gremlin> g.V(prometheus).drop();

  • Update vertex
nebula> UPDATE VERTEX hash("jesus") SET character.type = 'titan';
gremlin> g.V(jesus).property('age', 6000);
  • Fetch data

```bash nebula> FETCH PROP ON character hash("saturn"); =================================================== | character.name | character.age | character.type | =================================================== | saturn | 10000 | titan |


gremlin> g.V(saturn).valueMap(); ==>[name:[saturn],type:[titan],age:[10000]] ```

  • Find the name of hercules's grandfather

    ```bash nebula> GO 2 STEPS FROM hash("hercules") OVER father YIELD $$.character.name; ===================== | $$.character.name | ===================== | saturn |


    gremlin> g.V().hasLabel('character').has('name','hercules').out('father').out('father').values('name'); ==>saturn ```

  • Find the name of hercules's father

    ```bash nebula> GO FROM hash("hercules") OVER father YIELD $$.character.name; ===================== | $$.character.name | ===================== | jupiter |


    gremlin> g.V().hasLabel('character').has('name','hercules').out('father').values('name'); ==>jupiter ```

  • Find the characters with age > 100

    bash nebula> XXX # not supported yet gremlin> g.V().hasLabel('character').has('age',gt(100)).values('name'); ==>saturn ==>jupiter ==>neptune ==>pluto

  • Find who are pluto's cohabitants

    ```bash nebula> GO FROM hash("pluto") OVER lives YIELD lives._dst AS place | \ GO FROM $-.place OVER lives REVERSELY YIELD $$.character.name AS cohabitants; =============== | cohabitants | =============== | pluto |


    | cerberus |

    gremlin> g.V(pluto).out('lives').in('lives').values('name'); ==>pluto ==>cerberus ```

  • pluto can't be his own cohabitant

    ```bash 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 |


    gremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name'); ==>cerberus ```

  • Pluto's Brothers

    ```bash

    where do pluto's brothers live?

    nebula> GO FROM hash("pluto") OVER brother YIELD brother._dst AS brother | \ GO FROM $-.brother OVER lives YIELD $$.location.name; ==================== | $$.location.name | ==================== | sky |


    | sea |

    gremlin> g.V(pluto).out('brother').out('lives').values('name'); ==>sky ==>sea

    which brother lives in which place?

    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 |

    gremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god','place').by('name'); ==>[god:jupiter, place:sky] ==>[god:neptune, place:sea] ```