JanusGraph

AttentionThis page documents an earlier version. Go to the latest (v2.1)version.

In this tutorial, we are first going to setup JanusGraph to work with YugabyteDB as the underlying database. Then, using the Gremlin console, we are going to load some data and run some graph commands.

1. Start Local Cluster

Start a cluster on your local machine. Check that you are able to connect to YugabyteDB using cqlsh by doing the following.

  1. $ cqlsh
  1. Connected to local cluster at 127.0.0.1:9042.
  2. [cqlsh 5.0.1 | Cassandra 3.9-SNAPSHOT | CQL spec 3.4.2 | Native protocol v4]
  3. Use HELP for help.
  4. cqlsh>
  1. cqlsh> DESCRIBE KEYSPACES;
  1. system_schema system_auth system
  2. cqlsh>

2. Download JanusGraph

Download from the JanusGraph downloads page. This tutorial uses the 0.2.0 version of JanusGraph.

  1. $ wget https://github.com/JanusGraph/janusgraph/releases/download/v0.2.0/janusgraph-0.2.0-hadoop2.zip
  2. $ unzip janusgraph-0.2.0-hadoop2.zip
  3. $ cd janusgraph-0.2.0-hadoop2

3. Run JanusGraph with YugabyteDB

  • Start the Gremlin console by running ./bin/gremlin.sh. You should see something like the following.
  1. $ ./bin/gremlin.sh
  1. \,,,/
  2. (o o)
  3. -----oOOo-(3)-oOOo-----
  4. plugin activated: janusgraph.imports
  5. plugin activated: tinkerpop.server
  6. plugin activated: tinkerpop.utilities
  7. plugin activated: tinkerpop.hadoop
  8. plugin activated: tinkerpop.spark
  9. plugin activated: tinkerpop.tinkergraph
  10. gremlin>
  • Now use the CQL config to initialize JanusGraph to talk to Yugabyte.
  1. gremlin> graph = JanusGraphFactory.open('conf/janusgraph-cql.properties')
  1. ==>standardjanusgraph[cql:[127.0.0.1]]
  • Open the YugabyteDB UI to verify that the janusgraph keyspace and the necessary tables were created by opening the following URL in a web browser: http://localhost:7000/ (replace localhost with the ip address of any master node in a remote depoyment). You should see the following.

List of keyspaces and tables when running JanusGraph on YugabyteDB

4. Load Sample Data

We are going to load the sample data that JanusGraph ships with - the Graph of the Gods. You can do this by running the following:

  1. gremlin> GraphOfTheGodsFactory.loadWithoutMixedIndex(graph,true)
  1. ==>null
  1. gremlin> g = graph.traversal()
  1. ==>graphtraversalsource[standardjanusgraph[cql:[127.0.0.1]], standard]

5. Graph Traversal Examples

For reference, here is the graph data loaded by the Graph of the Gods. You can find a lot more useful information about this in the JanusGraph getting started page.

Graph of the Gods

  • Retrieve the Saturn vertex
  1. gremlin> saturn = g.V().has('name', 'saturn').next()
  2. ==>v[4168]
  • Who is Saturn’s grandchild?
  1. gremlin> g.V(saturn).in('father').in('father').values('name')
  2. ==>hercules
  • Queries about Hercules
  1. gremlin> hercules = g.V(saturn).repeat(__.in('father')).times(2).next()
  2. ==>v[4120]
  3. // Who were the parents of Hercules?
  4. gremlin> g.V(hercules).out('father', 'mother').values('name')
  5. ==>jupiter
  6. ==>alcmene
  7. // Were the parents of Hercules gods or humans?
  8. gremlin> g.V(hercules).out('father', 'mother').label()
  9. ==>god
  10. ==>human
  11. // Who did Hercules battle?
  12. gremlin> g.V(hercules).out('battled').valueMap()
  13. ==>[name:[hydra]]
  14. ==>[name:[nemean]]
  15. ==>[name:[cerberus]]
  16. // Who did Hercules battle after time 1?
  17. gremlin> g.V(hercules).outE('battled').has('time', gt(1)).inV().values('name')
  18. ==>cerberus
  19. ==>hydra

6. Complex Graph Traversal Examples

  • Who are Pluto’s cohabitants?
  1. gremlin> pluto = g.V().has('name', 'pluto').next()
  2. ==>v[8416]
  3. // who are pluto's cohabitants?
  4. gremlin> g.V(pluto).out('lives').in('lives').values('name')
  5. ==>pluto
  6. ==>cerberus
  7. // pluto can't be his own cohabitant
  8. gremlin> g.V(pluto).out('lives').in('lives').where(is(neq(pluto))).values('name')
  9. ==>cerberus
  10. gremlin> g.V(pluto).as('x').out('lives').in('lives').where(neq('x')).values('name')
  11. ==>cerberus
  12. gremlin>
  • Queries about Pluto’s Brothers.
  1. // where do pluto's brothers live?
  2. gremlin> g.V(pluto).out('brother').out('lives').values('name')
  3. ==>sea
  4. ==>sky
  5. // which brother lives in which place?
  6. gremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god', 'place')
  7. ==>[god:v[4248],place:v[4320]]
  8. ==>[god:v[8240],place:v[4144]]
  9. // what is the name of the brother and the name of the place?
  10. gremlin> g.V(pluto).out('brother').as('god').out('lives').as('place').select('god', 'place').by('name')
  11. ==>[god:neptune,place:sea]
  12. ==>[god:jupiter,place:sky]

7. Global Graph Index Examples

NOTE: Secondary indexes in YugabyteDB are coming soon. These queries will iterate over all vertices to find the result.

  • Geo-spatial indexes - events that have happened within 50 kilometers of Athens (latitude:37.97 and long:23.72).
  1. // Show all events that happened within 50 kilometers of Athens (latitude:37.97 and long:23.72).
  2. gremlin> g.E().has('place', geoWithin(Geoshape.circle(37.97, 23.72, 50)))
  3. ==>e[4cj-36g-7x1-6c8][4120-battled->8216]
  4. ==>e[3yb-36g-7x1-9io][4120-battled->12336]
  5. // For these events that happened within 50 kilometers of Athens, show who battled whom.
  6. gremlin> g.E().has('place', geoWithin(Geoshape.circle(37.97, 23.72, 50))).as('source').inV().as('god2').select('source').outV().as('god1').select('god1', 'god2').by('name')
  7. ==>[god1:hercules,god2:hydra]
  8. ==>[god1:hercules,god2:nemean]