SlideShare a Scribd company logo
The Gremlin Graph Traversal Language
Marko A. Rodriguez and Daniel Kuppitz
http://tinkerpop.incubator.apache.org
user movie categoryoccupation
occupation rated category
name:String
gender:[M,F]
age:integer
name:String
year:integer
name:String
stars:[1,2,3,4,5]
http://grouplens.org/datasets/movielens/
MovieLens Dataset
user
|Vuser| = 6040
|Vmovie| = 3883
movie
|Vcategory| = 18
category
|Voccupation| = 21
occupation
occupation
|Eoccupation| = 6040
rated
|Erated| = 1000209
category
|Ecategory| = 6408
name:String
gender:[M,F]
age:integer
name:String
year:integer
name:String
stars:[1,2,3,4,5]
http://grouplens.org/datasets/movielens/
G = (V, E)
MovieLens Dataset
~/tinkerpop3$ bin/gremlin.sh
gremlin>
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin>
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin>
Gremlin-Java8
Gremlin-Groovy*
Gremlin-Scala
Gremlin-Clojure
Gremlin-JavaScript
Gremlin-Python
Gremlin-PHP
...
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin>
"Create a new TinkerGraph."
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin>
"Create a new TinkerGraph."
G = (V = ∅, E = ∅)
G The graph is a set of vertices and edges
V The set of vertices in the graph
E The set of edges in the graph
∅ The empty set -- no elements
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin>
"Create a new TinkerGraph."
G = (V = ∅, E = ∅)
TitanGraph.open(…)
Neo4jGraph.open(…)
OrientGraph.open(…)
SqlgGraph.open(…)
HadoopGraph.open(…)
GiraphGraphComputer
SparkGraphComputer
ElasticGraph.open(…)
...
G = (V = ∅, E ⊆ (V × V ))
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin>
"Load the MovieLens dataset into the newly created TinkerGraph."
Set A is a subset of (or equal to) set B
The set of all ordered pairs of vertices (directed binary edges)
A ⊆ B
(V × V )
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin>
"Create a graph traversal source for spawning graph traversals over the MovieLens graph."
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin>
"Count the number of vertices in the graph."
|V | = 9962
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin>
"Count the number of vertices in the graph."
|V | = 9962
Vertex
map 9962
reducing barrier
Long
seed=0
value=seed
binary operator: value -> value+1
count()
{ "m
any-to-one"
Edge
map 1012657
reducing barrier
Long
|E| = 1012657
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin> g.E().count()
==>1012657
gremlin>
"Count the number of edges in the graph."
count()
{ "m
any-to-one"
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin> g.E().count()
==>1012657
gremlin> g.V().label().groupCount()
==>[occupation:21, movie:3883, category:18, user:6040]
gremlin>
"For each vertex in the graph, emit its label, then group and count each distinct label."
user
user
movie
category
...
Vertex String Map<String,Long>
user
user
movie
category
map map
reducing
barrier
[
occupation=21,
movie=3883,
category=18,
user=6040
]
label() groupCount(){"one-to-one" "many-to-one"
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin> g.E().count()
==>1012657
gremlin> g.V().label().groupCount()
==>[occupation:21, movie:3883, category:18, user:6040]
gremlin> g.E().hasLabel('rated').values('stars').mean()
==>3.581564453029317
gremlin>
"For each rated-edge in the graph, emit its stars property value and compute the average value."
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin> g.E().count()
==>1012657
gremlin> g.V().label().groupCount()
==>[occupation:21, movie:3883, category:18, user:6040]
gremlin> g.E().hasLabel('rated').values('stars').mean()
==>3.581564453029317
gremlin> g.V().hasLabel('user').map(outE('rated').count()).max()
==>2314
gremlin>
"What is the maximum number of movies a single user rated?"
~/tinkerpop3$ bin/gremlin.sh
,,,/
(o o)
-----oOOo-(3)-oOOo-----
plugin activated: tinkerpop.server
plugin activated: tinkerpop.utilities
plugin activated: tinkerpop.tinkergraph
gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo')
==>null
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> g.V().count()
==>9962
gremlin> g.E().count()
==>1012657
gremlin> g.V().label().groupCount()
==>[occupation:21, movie:3883, category:18, user:6040]
gremlin> g.E().hasLabel('rated').values('stars').mean()
==>3.581564453029317
gremlin> g.V().hasLabel('user').map(outE('rated').count()).max()
==>2314
gremlin> g.V().hasLabel('movie').values('year').min()
==>1919
gremlin>
"What year was the oldest movie made?"
gremlin> g.V().hasLabel('category').values('name')
==>Animation
==>Children's
==>Comedy
==>Adventure
==>Fantasy
==>Romance
==>Drama
==>Action
==>Crime
==>Thriller
==>Horror
==>Sci-Fi
==>Documentary
==>War
==>Musical
==>Mystery
==>Film-Noir
==>Western
"For each vertex that is labeled 'category,' emit the name property value of that vertex."
category
user
user
movie
category
Vertex
category
category
category
category
category
categorycategory
category
Vertex
Animation
Children's
Comedy
Adventure
Western
...
String
filter map
hasLabel('category') values('name')
"one-to-[one-or-none]" "one-to-one"
gremlin> g.V().hasLabel('category').as('a','b').
select('a','b').
by('name').
by(inE('category').count())
"For each category vertex, emit a map of its name and the number of movies it represents."
hasLabelcategory : V ∗
→ V ∗
gremlin> g.V().hasLabel('category').as('a','b').
select('a','b').
by('name').
by(inE('category').count())
"For each category vertex, emit a map of its name and the number of movies it represents."
V : G → V ∗
asa,b : V ∗
→ (V × V )∗
G The set of all graphs
f : A → B The function f maps values of type A to values of type B
A∗ A stream of values of type A
(A × B) The set of all pairs of values from A and B (cross product)
N The set of all natural numbers (1, 2, 3, 4, …)
The set of all strings (a, b, aa, ab, bb, …)
selecta,b : (V × V )∗
→
a valuesname : V ∗
→ S
b (inEcategory : V ∗
→ E∗
) ◦ (count : E∗
→ N)
→ (S × N)∗
S Σ∗
typically denoted
gremlin> g.V().hasLabel('category').as('a','b').
select('a','b').
by('name').
by(inE('category').count())
==>[a:Animation, b:105]
==>[a:Children's, b:251]
==>[a:Comedy, b:1200]
==>[a:Adventure, b:283]
==>[a:Fantasy, b:68]
==>[a:Romance, b:471]
==>[a:Drama, b:1603]
==>[a:Action, b:503]
==>[a:Crime, b:211]
==>[a:Thriller, b:492]
==>[a:Horror, b:343]
==>[a:Sci-Fi, b:276]
==>[a:Documentary, b:127]
==>[a:War, b:143]
==>[a:Musical, b:114]
==>[a:Mystery, b:106]
==>[a:Film-Noir, b:44]
==>[a:Western, b:68]
"For each category vertex, emit a map of its name and the number of movies it represents."
category
user
user
movie
category
Vertex
category
category
category
category
category
categorycategory
category
Vertex
[a:Animation, b:105]
[a:Children's, b:251]
[a:Comedy, b:1200]
[a:Adventure, b:283]
…
[a:Western, b:68]
Map<String,Long>
filter map
category
name:Animation
category
category
category
...
category
map map
reducing
barrier
105
Vertex Edge Long
category
name:Animation
Vertex String
map Animationa
b
map
flatMap
{"one-to-m
any"
"one-to-one"
gremlin> g.V().hasLabel('movie').as('a','b').
select('a','b').
by('name').
by(inE('rated').values('stars').mean()).
order().by(select('b'),decr).
limit(10)
"For each movie, emit a map of its name and average rating.
Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
gremlin> g.V().hasLabel('movie').as('a','b').
select('a','b').
by('name').
by(inE('rated').values('stars').mean()).
order().by(select('b'),decr).
limit(10)
==>[a:Charm's Incidents, b:NaN]
==>[a:Prerokbe Ognja, b:NaN]
==>[a:Leopard Son, The, b:NaN]
==>[a:Bird of Prey, b:NaN]
==>[a:Plutonium Circus, b:NaN]
==>[a:Hustler White, b:NaN]
==>[a:Curtis's Charm, b:NaN]
==>[a:Three Lives and Only One Death, b:NaN]
==>[a:Hoogste tijd, b:NaN]
==>[a:Entertaining Angels: The Dorothy Day Story, b:NaN]
category
user
user
movie
category
Vertex
movie
movie
movie
movie
movie
moviemovie
movie
Vertex
[a:Charm's Incidents, b:NaN]
[a:Prerokbe Ognja, b:NaN]
[a:Leopard Son, The, b:NaN]
[a:Bird of Prey, b:NaN]
...
[a:Entertaining Angels, b:NaN]
Map<String,Double>
filter map
movie
name:Charm's Incidents
map
reducing
barrier
NaN
Vertex Edge Double
movie
name:Charm's Incidents
Vertex String
map Charm's Incidentsa
b
map
map
Integer
...
"For each movie, emit a map of its name and average rating.
Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
flatMap
gremlin> g.V().hasLabel('movie').as('a','b').
select('a','b').
by('name').
by(coalesce(
inE('rated').values('stars'),
constant(0)).mean()).
order().by(select('b'),decr).
limit(10)
==>[a:Lured, b:5.0]
==>[a:One Little Indian, b:5.0]
==>[a:Bittersweet Motel, b:5.0]
==>[a:Gate of Heavenly Peace, The, b:5.0]
==>[a:Follow the Bitch, b:5.0]
==>[a:Schlafes Bruder (Brother of Sleep), b:5.0]
==>[a:Ulysses (Ulisse), b:5.0]
==>[a:Song of Freedom, b:5.0]
==>[a:Smashing Time, b:5.0]
==>[a:Baby, The, b:5.0]
"For each movie, get its name and mean rating (or 0 if no ratings). Order by average rating and emit top 10."
user
user
movie
category
Vertex
movie
movie
movie
movie
moviemovie
movie
Vertex Map<String,Double>
filter map
movie
name:Charm's Incidents
map map
reducing
barrier
0.0
Vertex Integer Double
movie
name:Charm's Incidents
Vertex String
map Charm's Incidentsa
b
map
0
[a:Lured, b:5.0]
[a:One Little Indian, b:5.0]
[a:Bittersweet Motel, b:5.0]
[a:Gate of Heavenly Peace, b:5.0]
...
[a:Baby, The, b:5.0]
Map<String,Double>
map
[a:Charm's Incidents, b:NaN]
[a:Prerokbe Ognja, b:NaN]
[a:Leopard Son, The, b:NaN]
[a:Bird of Prey, b:NaN]
...
[a:Entertaining Angels, b:NaN]
collecting
barrier
gremlin> g.V().hasLabel('movie').as('a','b').
where(inE('rated').count().is(gt(10))).
select('a','b').
by('name').
by(inE('rated').values('stars').mean()).
order().by(select('b'),decr).
limit(10)
"For each movie with at least 11 ratings, emit a map of its name and average rating.
Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
gremlin> g.V().hasLabel('movie').as('a','b').
where(inE('rated').count().is(gt(10))).
select('a','b').
by('name').
by(inE('rated').values('stars').mean()).
order().by(select('b'),decr).
limit(10)
==>[a:Sanjuro, b:4.608695652173913]
==>[a:Seven Samurai (The Magnificent Seven), b:4.560509554140127]
==>[a:Shawshank Redemption, The, b:4.554557700942973]
==>[a:Godfather, The, b:4.524966261808367]
==>[a:Close Shave, A, b:4.52054794520548]
==>[a:Usual Suspects, The, b:4.517106001121705]
==>[a:Schindler's List, b:4.510416666666667]
==>[a:Wrong Trousers, The, b:4.507936507936508]
==>[a:Sunset Blvd. (a.k.a. Sunset Boulevard), b:4.491489361702127]
==>[a:Raiders of the Lost Ark, b:4.47772]
"For each movie with at least 11 ratings, emit a map of its name and average rating.
Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
map
movie
name:Sanjuro
rated
rated
rated
...
rated
map
reducing
barrier
4.60
Vertex Edge Double
movie
name:Sanjuro
Vertex String
map Sanjuroa
b
map
map
Integer
user
user
movie
category
Vertex
movie
movie
movie
movie
moviemovie
movie
Vertex
filter
movie
rated
rated
rated
...
rated
reducing
barrier
Vertex Edge
map
Long
69
name:Sanjuro
filter
movie
movie
movie
movie
movie
Vertex
5
4
…
5
[[a:Sanjuro, b:4.60]
[a:Seven Samurai, b:4.56]
[a:Shawshank Redemption, b:4.55]
[a:Godfather, The, b:4.52]
...
[a:Raiders of the Lost Ark, b:4.47]
[…]
[…]
[…]
[…]
…
[…]
Map<String,Double> Map<String,Double>
map
collecting
barrier
flatMap
flatMap
{
{
gremlin> g.V().hasLabel('movie').
where(inE('rated').count().is(gt(10))).
toString()
==>[GraphStep([],vertex), HasStep([~label.eq(movie)]),
TraversalFilterStep([
VertexStep(IN,[rated],edge),
CountGlobalStep,
IsStep(gt(10))])]
"What is the execution plan for the traversal prior to compiler optimizations being applied?"
V : G → V ∗
hasLabelmovie : V ∗
→ V ∗
where : V ∗
→
inErated : V ∗
→ E∗
count : E∗
→ N
isgt(10) : N → (N ∪ ∅)
→ V ∗
"true
orfalse"
gremlin> g.V().hasLabel('movie').
where(inE('rated').count().is(gt(10))).
iterate().toString()
==>[TinkerGraphStep(vertex,[~label.eq(movie)]),
TraversalFilterStep([
VertexStep(IN,[rated],edge),
RangeGlobalStep(0,11),
CountGlobalStep,
IsStep(gt(10))])]
"What is the execution plan for the traversal after compiler optimizations have been applied?"
* TinkerGraphStragegy: Access vendor-specific vertex partition by label.
* RangeByIsCountStrategy: Only iterate 1 more than required count.
where : V ∗
→
inErated : V ∗
→ E∗
count : E∗
→ N
isgt(10) : N → (N ∪ ∅)
limit11 : E∗
→ E∗
Vlabel=movie : G → V ∗
→ V ∗
"true
orfalse"
gremlin> g.getStrategies()
==>ConjunctionStrategy
a.and().b => and(a,b)
a.or().b => or(a,b)
a.or().b.and().c => or(a,and(b,c))
a.and().b.or().c => or(and(a,b),c)
==>IncidentToAdjacentStrategy
a.outE().inV().b => a.out().b
==>AdjacentToIncidentStrategy
a.in().count().b => a.inE().count().b
a.where(out()).b => a.where(outE()).b
a.and(in(),out()).b => a.and(inE(),outE()).b
==>IdentityRemovalStrategy
a.identity().b => a.b
==>FilterRankingStrategy
a.order().dedup().b => a.dedup().order().b
a.and(c,d).has().b => a.has().and(c,d).b
a.simplePath().where().b => b.where().simplePath().a
==>MatchPredicateStrategy
a.match(c,d).where(e).b => a.match(c,d,e)
a.match(has(),c,d).b => a.has().match(c,d).b
==>RangeByIsCountStrategy
a.count().is(0) => a.limit(1).count().is(0)
==>TinkerGraphStepStrategy
V.has().has().b => V[has,has].b
==>ProfileStrategy
a.b.c.profile() => a.profile().b.profile().c.profile()
==>ComputerVerificationStrategy
a.order.b => IllegalStateException
a.local(out().out()).b => IllegalStateException
"What compilation strategies are associated with the graph traversal source?"
gremlin> g.V().has('movie','name','Die Hard').
inE('rated').values('stars').mean()
==>4.121848739495798
"What is Die Hard's average rating?"
gremlin> g.V().has('movie','name','Die Hard').
inE('rated').values('stars').mean()
==>4.121848739495798
"What is Die Hard's average rating?"
movie
movie
movie
Vertex
movie
Vertex
filter
name:Die Hard
flatMap
rated
rated
rated
...
rated
Edge
map
3
5
5
…
4
Integer
map
Double
4.1218
reducing
barrier
V : G → V ∗
hasLabelmovie : V ∗
→ V ∗
hasname=Die Hard : V ∗
→ V ∗
inErated : V ∗
→ E∗ mean : N∗
→ R
valuesstars : E∗
→ N∗
user
user
movie
user
Vertex
filter
{
"one-to-[one-or-none]"
"one-to-[one-or-none]"
"one-to-many"
"one-to-one"
"many-to-one"
gremlin> g.V().has('movie','name','Die Hard').as('a').
inE('rated').has('stars',5).outV().
where(out('occupation').has('name','programmer')).
outE('rated').has('stars',5).inV().
where(neq('a')).
groupCount().by('name').
order(local).by(valueDecr).
limit(local,10).
unfold() // so its not printed on a single line
"Which programmers like Die Hard and what other movies do they like?
Group and count the movies by their name. Sort the group count map in decreasing order by the count.
Clip the map to the top 10 entries and stream out the map's entries (for display purposes)."
gremlin> g.V().has('movie','name','Die Hard').as('a').
inE('rated').has('stars',5).outV().
where(out('occupation').has('name','programmer')).
outE('rated').has('stars',5).inV().
where(neq('a')).
groupCount().by('name').
order(local).by(valueDecr).
limit(local,10).
unfold() // so its not printed on a single line
"Which programmers like Die Hard and what other movies do they like?
Group and count the movies by their name. Sort the group count map in decreasing order by the count.
Clip the map to the top 10 entries and stream out the map's entries (for display purposes)."
user
user
movie
user
Vertex
movie
Vertex
filter filter
name:Die Hard
flatMap
rated
rated
rated
...
rated
Edge
filter
rated
...
rated
Edge
map
Vertex
user
user
user
useruser
user
Vertex Vertex
occupationflatMap
Vertex
filter
rated
rated
rated
...
rated
Edge
filter
rated
...
rated
Edge
map
Vertex
movie
movie
moviemovie
movie
Vertex
Vertex
user
user
user
flatMap filter movie
Vertex
filter
Vertex
movie
movie
movie
map
reducing
barrier
[
Aliens=105,
Braveheart=24,
…
Pulp Fiction=19
]
Map<String,Long>
map
collecting
barrier
[
Raider of the Lost Ark=36,
Star Wars: Episode V=24,
Star Wars: Episode IV=34
…
Airplane II: The Sequel=1
]
Map<String,Long>
[
Raider of the Lost Ark=36,
Star Wars: Episode V=24,
Star Wars: Episode IV=34
…
Alien=22
]
Map<String,Long>
map
occupation
programmer
not Die Hard
gremlin> g.V().has('movie','name','Die Hard').as('a').
inE('rated').has('stars',5).outV().
where(out('occupation').has('name','programmer')).
outE('rated').has('stars',5).inV().
where(neq('a')).
groupCount().by('name').
order(local).by(valueDecr).
limit(local,10).
unfold() // so its not printed on a single line
==>Raiders of the Lost Ark=36
==>Star Wars: Episode V - The Empire Strikes Back=36
==>Star Wars: Episode IV - A New Hope=34
==>Matrix, The=32
==>Terminator, The=29
==>Star Wars: Episode VI - Return of the Jedi=26
==>Sixth Sense, The=26
==>Braveheart=24
==>Aliens=23
==>Alien=22
gremlin>
"Which programmers like Die Hard and what other movies do they like?
Group and count the movies by their name. Sort the group count map in decreasing order by the count.
Clip the map to the top 10 entries and stream out the map's entries (for display purposes)."
gremlin> g.V().
match(
__.as('a').hasLabel('movie'),
__.as('a').out('category').has('name','Action'),
__.as('a').has('year',between(1980,1990)),
__.as('a').inE('rated').as('b'),
__.as('b').has('stars',5),
__.as('b').outV().as('c'),
__.as('c').out('occupation').has('name','programmer'),
__.as('c').has('age',between(30,40))).
select('a').groupCount().by('name').
order(local).by(valueDecr).
limit(local,10).
unfold() // so its not printed on a single line
"What 80's action movies do 30-something programmers like?
Group count the movies by their name and sort the group count map in decreasing order by value.
Clip the map to the top 10 and emit the map entries."
"What 80's action movies do 30-something programmers like?
Group count the movies by their name and sort the group count map in decreasing order by value.
Clip the map to the top 10 and emit the map entries."
gremlin> g.V().
match(
__.as('a').hasLabel('movie'),
__.as('a').out('category').has('name','Action'),
__.as('a').has('year',between(1980,1990)),
__.as('a').inE('rated').as('b'),
__.as('b').has('stars',5),
__.as('b').outV().as('c'),
__.as('c').out('occupation').has('name','programmer'),
__.as('c').has('age',between(30,40))).
select('a').groupCount().by('name').
order(local).by(valueDecr).
limit(local,10).
unfold() // so its not printed on a single line
==>Raiders of the Lost Ark=26
==>Star Wars: Episode V - The Empire Strikes Back=26
==>Terminator, The=23
==>Star Wars: Episode VI - Return of the Jedi=22
==>Princess Bride, The=19
==>Aliens=18
==>Boat, The (Das Boot)=11
==>Indiana Jones and the Last Crusade=11
==>Star Trek: The Wrath of Khan=10
==>Abyss, The=9
gremlin>
MatchStep
GraphTraversal.match(Traversal... traversalPatterns)
x.match(
a...b
a...c
c...
or(
a...c
a...b
)
c.repeat(...).b
not(c...a)
b...count().e
c...count().e
).dedup(a,b).y
a,b,c,e : once a variable is set, it must hold equal for all patterns
c... : "predicate patterns" simply check for the existence of a result
or()/and() : nested conjunctive patterns supported
repeat(...) : recursive patterns supported
not(...) : not'ing of patterns supported
count() : barrier patterns supported
dedup(a,b) : internal de-duplication of variable values supported
x.match().y : possible to go from imperative to declarative, etc.
Plug and Play MatchAlgorithms
GreedyMatchAlgorithm :
try each pattern in the order provided by the user
CountMatchAlgorithm :
continually re-sort patterns by the cardinality of their set reductions
// CountMatchAlgorithm (default)
gremlin> clockWithResult(50){
g.V().match(
__.as('a').out('rated').as('b'),
__.as('a').out('occupation').has('name','farmer')).
select('a','b').count().next()}
==>66.31955294 // time in milliseconds
==>2706 // number of results
// GreedyMatchAlgorithm
gremlin> g = graph.traversal(GraphTraversalSource.build().
with(MatchAlgorithmStrategy.build().
algorithm(MatchStep.GreedyMatchAlgorithm).create()))
==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard]
gremlin> clockWithResult(50){
g.V().match(
__.as('a').out('rated').as('b'),
__.as('a').out('occupation').has('name','farmer')).
select('a','b').count().next()}
==>1902.6290871599997 // time in milliseconds
==>2706 // number of results
"Which movies did each farmer rate? -- benchmark CountMatchAlgorithm vs. GreedyMatchAlgorithm."
farmermoviesusers
1000209 2706
farmer moviesusers
17 2706
gremlin> g.V().hasLabel('movie').
where(inE('rated').count().is(gt(10))).
group().
by{((int)(it.value('year') / 10)) * 10}.
by().
by(unfold().order().
by(inE('rated').values('stars').mean(),decr).
values('name').
limit(1)).
order(local).by(keyIncr).
unfold() // so its not printed on a single line
"What is the most liked movie in each decade?"
gremlin> g.V().hasLabel('movie').
where(inE('rated').count().is(gt(10))).
group().
by{((int)(it.value('year') / 10)) * 10}.
by().
by(unfold().order().
by(inE('rated').values('stars').mean(),decr).
values('name').
limit(1)).
order(local).by(keyIncr).
unfold() // so its not printed on a single line
"What is the most liked movie in each decade?"
λ
λ
Nearly every step that takes a traversal argument can also take a lambda.
It is recommended that users do not use lambdas as they are not subject to traversal strategy (i.e. compiler) optimization.
However, they are useful when no provided step yields the desired computation.
gremlin> g.V().hasLabel('movie').
where(inE('rated').count().is(gt(10))).
group().
by{((int)(it.value('year') / 10)) * 10}.
by().
by(unfold().order().
by(inE('rated').values('stars').mean(),decr).
values('name').
limit(1)).
order(local).by(keyIncr).
unfold() // so its not printed on a single line
==>1910=Daddy Long Legs
==>1920=General, The
==>1930=City Lights
==>1940=Third Man, The
==>1950=Seven Samurai (The Magnificent Seven)
==>1960=Sanjuro
==>1970=Godfather, The
==>1980=Raiders of the Lost Ark
==>1990=Shawshank Redemption, The
==>2000=Almost Famous
gremlin>
"What is the most liked movie in each decade?"
gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties')
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin> g = graph.traversal(computer(SparkGraphComputer))
==>graphtraversalsource
[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
gremlin>
"Which movies are most central in the implicit 5-stars graph?"
gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties')
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin> g = graph.traversal(computer(SparkGraphComputer))
==>graphtraversalsource
[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
gremlin> g.V().repeat(outE('rated').has('stars', 5).inV().
groupCount('m').by('name').
inE('rated').has('stars', 5).outV()).
times(4).cap('m')
"Which movies are most central in the implicit 5-stars graph?"
user movie user
ratedrated
m
4x
cap('m')
repeat(…).times(4)
g.V()
stars=5 stars=5
gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties')
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin> g = graph.traversal(computer(SparkGraphComputer))
==>graphtraversalsource
[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
gremlin> g.V().repeat(outE('rated').has('stars', 5).inV().
groupCount('m').by('name').
inE('rated').has('stars', 5).outV()).
times(4).cap('m')
==>Fantasia 2000=2676505178171564
==>Pale Rider=1369969000295362
==>Crucible, The=401712993698149
==>About Adam=37981148456999
==>Akira=3659939409345918
...
gremlin>
"Which movies are most central in the implicit 5-stars graph?"
gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties')
==>hadoopgraph[gryoinputformat->gryooutputformat]
gremlin> g = graph.traversal(computer(SparkGraphComputer))
==>graphtraversalsource
[hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer]
gremlin> g.V().repeat(outE('rated').has('stars', 5).inV().
groupCount('m').by('name').
inE('rated').has('stars', 5).outV()).
times(4).cap('m')
==>Fantasia 2000=2676505178171564
==>Pale Rider=1369969000295362
==>Crucible, The=401712993698149
==>About Adam=37981148456999
==>Akira=3659939409345918
...
gremlin> hdfs.ls('output/m')
==>rw-r--r-- daniel supergroup 0 _SUCCESS
==>rw-r--r-- daniel supergroup 245314 part-r-00000
gremlin> hdfs.head('output/m', ObjectWritable).sort {-it.value}.take(10)
==>Star Wars: Episode IV - A New Hope 35405394353105332
==>American Beauty 31943228282020585
==>Raiders of the Lost Ark 31224779793238499
==>Star Wars: Episode V - The Empire Strikes Back 30434677119726223
==>Godfather, The 30258518523013057
==>Shawshank Redemption, The 28297717387901031
==>Schindler's List 27539336654199309
==>Silence of the Lambs, The 26736276376806173
==>Fargo 26531050311325270
==>Matrix, The 26395118239203191
"Which movies are most central in the implicit 5-stars graph?"
gremlin> :plugin use tinkerpop.gephi
==>tinkerpop.gephi activated
gremlin> :remote connect tinkerpop.gephi
==>Connection to Gephi - http://localhost:8080/workspace0 with stepDelay:1000,
startRGBColor:[0.0, 1.0, 0.5], colorToFade:g, colorFadeRate:0.7, startSize:
20.0,sizeDecrementRate:0.33
gremlin>
gremlin> :plugin use tinkerpop.gephi
==>tinkerpop.gephi activated
gremlin> :remote connect tinkerpop.gephi
==>Connection to Gephi - http://localhost:8080/workspace0 with stepDelay:1000,
startRGBColor:[0.0, 1.0, 0.5], colorToFade:g, colorFadeRate:0.7, startSize:
20.0,sizeDecrementRate:0.33
gremlin> :> g.V().hasLabel('user').
order().
by(outE('rated').count(), decr).limit(10).as('a').
local(outE('rated').order().
by('stars', decr). // first by stars
by(inV().inE('rated').count(), decr). // then by ratings
limit(10)).
subgraph('sg').inV().outE('category').
subgraph('sg').select('a').outE('occupation').
subgraph('sg').cap('sg').next()
==>tinkergraph[vertices:82 edges:233]
gremlin>
"Which users rated the most movies?
For each user, display their 10 favorite movies, the categories of those movies, and their occupation.
"moviebuffs"
Thanks for listening…

More Related Content

What's hot

Efficient Data Storage for Analytics with Apache Parquet 2.0
Efficient Data Storage for Analytics with Apache Parquet 2.0Efficient Data Storage for Analytics with Apache Parquet 2.0
Efficient Data Storage for Analytics with Apache Parquet 2.0
Cloudera, Inc.
 

What's hot (20)

Apache spark
Apache sparkApache spark
Apache spark
 
A Tale of Two Graph Frameworks on Spark: GraphFrames and Tinkerpop OLAP Artem...
A Tale of Two Graph Frameworks on Spark: GraphFrames and Tinkerpop OLAP Artem...A Tale of Two Graph Frameworks on Spark: GraphFrames and Tinkerpop OLAP Artem...
A Tale of Two Graph Frameworks on Spark: GraphFrames and Tinkerpop OLAP Artem...
 
Efficient Data Storage for Analytics with Apache Parquet 2.0
Efficient Data Storage for Analytics with Apache Parquet 2.0Efficient Data Storage for Analytics with Apache Parquet 2.0
Efficient Data Storage for Analytics with Apache Parquet 2.0
 
[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on Kubernetes[Outdated] Secrets of Performance Tuning Java on Kubernetes
[Outdated] Secrets of Performance Tuning Java on Kubernetes
 
Flink vs. Spark
Flink vs. SparkFlink vs. Spark
Flink vs. Spark
 
Achieve Blazing-Fast Ingest Speeds with Apache Arrow
Achieve Blazing-Fast Ingest Speeds with Apache ArrowAchieve Blazing-Fast Ingest Speeds with Apache Arrow
Achieve Blazing-Fast Ingest Speeds with Apache Arrow
 
Thrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased ComparisonThrift vs Protocol Buffers vs Avro - Biased Comparison
Thrift vs Protocol Buffers vs Avro - Biased Comparison
 
Galene - LinkedIn's Search Architecture: Presented by Diego Buthay & Sriram S...
Galene - LinkedIn's Search Architecture: Presented by Diego Buthay & Sriram S...Galene - LinkedIn's Search Architecture: Presented by Diego Buthay & Sriram S...
Galene - LinkedIn's Search Architecture: Presented by Diego Buthay & Sriram S...
 
Intro to Neo4j
Intro to Neo4jIntro to Neo4j
Intro to Neo4j
 
Intro to Neo4j and Graph Databases
Intro to Neo4j and Graph DatabasesIntro to Neo4j and Graph Databases
Intro to Neo4j and Graph Databases
 
The Apache Solr Semantic Knowledge Graph
The Apache Solr Semantic Knowledge GraphThe Apache Solr Semantic Knowledge Graph
The Apache Solr Semantic Knowledge Graph
 
Spark streaming , Spark SQL
Spark streaming , Spark SQLSpark streaming , Spark SQL
Spark streaming , Spark SQL
 
Storing 16 Bytes at Scale
Storing 16 Bytes at ScaleStoring 16 Bytes at Scale
Storing 16 Bytes at Scale
 
Graph Databases
Graph DatabasesGraph Databases
Graph Databases
 
Designing and Building a Graph Database Application – Architectural Choices, ...
Designing and Building a Graph Database Application – Architectural Choices, ...Designing and Building a Graph Database Application – Architectural Choices, ...
Designing and Building a Graph Database Application – Architectural Choices, ...
 
Introduction to ML with Apache Spark MLlib
Introduction to ML with Apache Spark MLlibIntroduction to ML with Apache Spark MLlib
Introduction to ML with Apache Spark MLlib
 
HTTP Analytics for 6M requests per second using ClickHouse, by Alexander Boc...
HTTP Analytics for 6M requests per second using ClickHouse, by  Alexander Boc...HTTP Analytics for 6M requests per second using ClickHouse, by  Alexander Boc...
HTTP Analytics for 6M requests per second using ClickHouse, by Alexander Boc...
 
Apache Spark Architecture
Apache Spark ArchitectureApache Spark Architecture
Apache Spark Architecture
 
Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28Neptune, the Graph Database | AWS Floor28
Neptune, the Graph Database | AWS Floor28
 
Near real-time anomaly detection at Lyft
Near real-time anomaly detection at LyftNear real-time anomaly detection at Lyft
Near real-time anomaly detection at Lyft
 

Viewers also liked

Cassandra Virtual Node talk
Cassandra Virtual Node talkCassandra Virtual Node talk
Cassandra Virtual Node talk
Patrick McFadin
 

Viewers also liked (20)

ACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and LanguageACM DBPL Keynote: The Graph Traversal Machine and Language
ACM DBPL Keynote: The Graph Traversal Machine and Language
 
Quantum Processes in Graph Computing
Quantum Processes in Graph ComputingQuantum Processes in Graph Computing
Quantum Processes in Graph Computing
 
Gremlin: A Graph-Based Programming Language
Gremlin: A Graph-Based Programming LanguageGremlin: A Graph-Based Programming Language
Gremlin: A Graph-Based Programming Language
 
Cassandra Summit - What's New In Apache TinkerPop?
Cassandra Summit - What's New In Apache TinkerPop?Cassandra Summit - What's New In Apache TinkerPop?
Cassandra Summit - What's New In Apache TinkerPop?
 
Intro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
Intro to Graph Databases Using Tinkerpop, TitanDB, and GremlinIntro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
Intro to Graph Databases Using Tinkerpop, TitanDB, and Gremlin
 
The Path Forward
The Path ForwardThe Path Forward
The Path Forward
 
The Gremlin in the Graph
The Gremlin in the GraphThe Gremlin in the Graph
The Gremlin in the Graph
 
Titan: Big Graph Data with Cassandra
Titan: Big Graph Data with CassandraTitan: Big Graph Data with Cassandra
Titan: Big Graph Data with Cassandra
 
Solving Problems with Graphs
Solving Problems with GraphsSolving Problems with Graphs
Solving Problems with Graphs
 
Cassandra Virtual Node talk
Cassandra Virtual Node talkCassandra Virtual Node talk
Cassandra Virtual Node talk
 
Temporal dynamics of human behavior in social networks (i)
Temporal dynamics of human behavior in social networks (i)Temporal dynamics of human behavior in social networks (i)
Temporal dynamics of human behavior in social networks (i)
 
Putting the Dance Theatre of Harlem Archives Back Together
Putting the Dance Theatre of Harlem Archives Back TogetherPutting the Dance Theatre of Harlem Archives Back Together
Putting the Dance Theatre of Harlem Archives Back Together
 
European Government Bond Correlation Dynamics: Taming Contagion Risks
European Government Bond Correlation Dynamics: Taming Contagion RisksEuropean Government Bond Correlation Dynamics: Taming Contagion Risks
European Government Bond Correlation Dynamics: Taming Contagion Risks
 
Titan: The Rise of Big Graph Data
Titan: The Rise of Big Graph DataTitan: The Rise of Big Graph Data
Titan: The Rise of Big Graph Data
 
Network Approaches for Interbank Markets
Network Approaches for Interbank MarketsNetwork Approaches for Interbank Markets
Network Approaches for Interbank Markets
 
DataStax: What's New in Apache TinkerPop - the Graph Computing Framework
DataStax: What's New in Apache TinkerPop - the Graph Computing FrameworkDataStax: What's New in Apache TinkerPop - the Graph Computing Framework
DataStax: What's New in Apache TinkerPop - the Graph Computing Framework
 
F8 tech talk_pinterest_v4
F8 tech talk_pinterest_v4F8 tech talk_pinterest_v4
F8 tech talk_pinterest_v4
 
Seda an architecture for well-conditioned scalable internet services
Seda   an architecture for well-conditioned scalable internet servicesSeda   an architecture for well-conditioned scalable internet services
Seda an architecture for well-conditioned scalable internet services
 
Facebook's TAO & Unicorn data storage and search platforms
Facebook's TAO & Unicorn data storage and search platformsFacebook's TAO & Unicorn data storage and search platforms
Facebook's TAO & Unicorn data storage and search platforms
 
Data Driven Growth
Data Driven GrowthData Driven Growth
Data Driven Growth
 

Similar to The Gremlin Graph Traversal Language

A gentle introduction to functional programming through music and clojure
A gentle introduction to functional programming through music and clojureA gentle introduction to functional programming through music and clojure
A gentle introduction to functional programming through music and clojure
Paul Lam
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to Gremlin
Max De Marzi
 

Similar to The Gremlin Graph Traversal Language (20)

The Ring programming language version 1.8 book - Part 53 of 202
The Ring programming language version 1.8 book - Part 53 of 202The Ring programming language version 1.8 book - Part 53 of 202
The Ring programming language version 1.8 book - Part 53 of 202
 
Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9Simulator customizing & testing for Xcode 9
Simulator customizing & testing for Xcode 9
 
A gentle introduction to functional programming through music and clojure
A gentle introduction to functional programming through music and clojureA gentle introduction to functional programming through music and clojure
A gentle introduction to functional programming through music and clojure
 
Fact, Fiction, and FP
Fact, Fiction, and FPFact, Fiction, and FP
Fact, Fiction, and FP
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184
 
imager package in R and examples..
imager package in R and examples..imager package in R and examples..
imager package in R and examples..
 
Groovy and Grails talk
Groovy and Grails talkGroovy and Grails talk
Groovy and Grails talk
 
Python 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptxPython 03-parameters-graphics.pptx
Python 03-parameters-graphics.pptx
 
The secrets of inverse brogramming
The secrets of inverse brogrammingThe secrets of inverse brogramming
The secrets of inverse brogramming
 
Amazon SageMaker을 통한 손쉬운 Jupyter Notebook 활용하기 - 윤석찬 (AWS 테크에반젤리스트)
Amazon SageMaker을 통한 손쉬운 Jupyter Notebook 활용하기  - 윤석찬 (AWS 테크에반젤리스트)Amazon SageMaker을 통한 손쉬운 Jupyter Notebook 활용하기  - 윤석찬 (AWS 테크에반젤리스트)
Amazon SageMaker을 통한 손쉬운 Jupyter Notebook 활용하기 - 윤석찬 (AWS 테크에반젤리스트)
 
Recommendation Engine with In-Database Machine Learning
Recommendation Engine with In-Database Machine LearningRecommendation Engine with In-Database Machine Learning
Recommendation Engine with In-Database Machine Learning
 
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak   CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
CONFidence 2015: DTrace + OSX = Fun - Andrzej Dyjak
 
dplyr
dplyrdplyr
dplyr
 
R programming language
R programming languageR programming language
R programming language
 
Introduction to Gremlin
Introduction to GremlinIntroduction to Gremlin
Introduction to Gremlin
 
The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185
 
The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210The Ring programming language version 1.9 book - Part 56 of 210
The Ring programming language version 1.9 book - Part 56 of 210
 
Do snow.rwn
Do snow.rwnDo snow.rwn
Do snow.rwn
 
ECMAScript 6, o cómo usar el JavaScript del futuro hoy
ECMAScript 6, o cómo usar el JavaScript del futuro hoyECMAScript 6, o cómo usar el JavaScript del futuro hoy
ECMAScript 6, o cómo usar el JavaScript del futuro hoy
 
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
Kotlin - The Swiss army knife of programming languages - Visma Mobile Meet-up...
 

More from Marko Rodriguez

Memoirs of a Graph Addict: Despair to Redemption
Memoirs of a Graph Addict: Despair to RedemptionMemoirs of a Graph Addict: Despair to Redemption
Memoirs of a Graph Addict: Despair to Redemption
Marko Rodriguez
 
The Network Data Structure in Computing
The Network Data Structure in ComputingThe Network Data Structure in Computing
The Network Data Structure in Computing
Marko Rodriguez
 
A Model of the Scholarly Community
A Model of the Scholarly CommunityA Model of the Scholarly Community
A Model of the Scholarly Community
Marko Rodriguez
 

More from Marko Rodriguez (20)

mm-ADT: A Virtual Machine/An Economic Machine
mm-ADT: A Virtual Machine/An Economic Machinemm-ADT: A Virtual Machine/An Economic Machine
mm-ADT: A Virtual Machine/An Economic Machine
 
mm-ADT: A Multi-Model Abstract Data Type
mm-ADT: A Multi-Model Abstract Data Typemm-ADT: A Multi-Model Abstract Data Type
mm-ADT: A Multi-Model Abstract Data Type
 
Open Problems in the Universal Graph Theory
Open Problems in the Universal Graph TheoryOpen Problems in the Universal Graph Theory
Open Problems in the Universal Graph Theory
 
Gremlin 101.3 On Your FM Dial
Gremlin 101.3 On Your FM DialGremlin 101.3 On Your FM Dial
Gremlin 101.3 On Your FM Dial
 
Faunus: Graph Analytics Engine
Faunus: Graph Analytics EngineFaunus: Graph Analytics Engine
Faunus: Graph Analytics Engine
 
The Pathology of Graph Databases
The Pathology of Graph DatabasesThe Pathology of Graph Databases
The Pathology of Graph Databases
 
The Path-o-Logical Gremlin
The Path-o-Logical GremlinThe Path-o-Logical Gremlin
The Path-o-Logical Gremlin
 
Memoirs of a Graph Addict: Despair to Redemption
Memoirs of a Graph Addict: Despair to RedemptionMemoirs of a Graph Addict: Despair to Redemption
Memoirs of a Graph Addict: Despair to Redemption
 
Graph Databases: Trends in the Web of Data
Graph Databases: Trends in the Web of DataGraph Databases: Trends in the Web of Data
Graph Databases: Trends in the Web of Data
 
Problem-Solving using Graph Traversals: Searching, Scoring, Ranking, and Reco...
Problem-Solving using Graph Traversals: Searching, Scoring, Ranking, and Reco...Problem-Solving using Graph Traversals: Searching, Scoring, Ranking, and Reco...
Problem-Solving using Graph Traversals: Searching, Scoring, Ranking, and Reco...
 
A Perspective on Graph Theory and Network Science
A Perspective on Graph Theory and Network ScienceA Perspective on Graph Theory and Network Science
A Perspective on Graph Theory and Network Science
 
The Graph Traversal Programming Pattern
The Graph Traversal Programming PatternThe Graph Traversal Programming Pattern
The Graph Traversal Programming Pattern
 
The Network Data Structure in Computing
The Network Data Structure in ComputingThe Network Data Structure in Computing
The Network Data Structure in Computing
 
A Model of the Scholarly Community
A Model of the Scholarly CommunityA Model of the Scholarly Community
A Model of the Scholarly Community
 
General-Purpose, Internet-Scale Distributed Computing with Linked Process
General-Purpose, Internet-Scale Distributed Computing with Linked ProcessGeneral-Purpose, Internet-Scale Distributed Computing with Linked Process
General-Purpose, Internet-Scale Distributed Computing with Linked Process
 
Collective Decision Making Systems: From the Ideal State to Human Eudaimonia
Collective Decision Making Systems: From the Ideal State to Human EudaimoniaCollective Decision Making Systems: From the Ideal State to Human Eudaimonia
Collective Decision Making Systems: From the Ideal State to Human Eudaimonia
 
Distributed Graph Databases and the Emerging Web of Data
Distributed Graph Databases and the Emerging Web of DataDistributed Graph Databases and the Emerging Web of Data
Distributed Graph Databases and the Emerging Web of Data
 
An Overview of Data Management Paradigms: Relational, Document, and Graph
An Overview of Data Management Paradigms: Relational, Document, and GraphAn Overview of Data Management Paradigms: Relational, Document, and Graph
An Overview of Data Management Paradigms: Relational, Document, and Graph
 
Graph Databases and the Future of Large-Scale Knowledge Management
Graph Databases and the Future of Large-Scale Knowledge ManagementGraph Databases and the Future of Large-Scale Knowledge Management
Graph Databases and the Future of Large-Scale Knowledge Management
 
Automatic Metadata Generation using Associative Networks
Automatic Metadata Generation using Associative NetworksAutomatic Metadata Generation using Associative Networks
Automatic Metadata Generation using Associative Networks
 

Recently uploaded

Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
mbmh111980
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
Alluxio, Inc.
 

Recently uploaded (20)

GraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysisGraphAware - Transforming policing with graph-based intelligence analysis
GraphAware - Transforming policing with graph-based intelligence analysis
 
Cyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdfCyaniclab : Software Development Agency Portfolio.pdf
Cyaniclab : Software Development Agency Portfolio.pdf
 
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAGAI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
AI/ML Infra Meetup | Reducing Prefill for LLM Serving in RAG
 
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdfMastering Windows 7 A Comprehensive Guide for Power Users .pdf
Mastering Windows 7 A Comprehensive Guide for Power Users .pdf
 
Studiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting softwareStudiovity film pre-production and screenwriting software
Studiovity film pre-production and screenwriting software
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
Prosigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology SolutionsProsigns: Transforming Business with Tailored Technology Solutions
Prosigns: Transforming Business with Tailored Technology Solutions
 
Crafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM IntegrationCrafting the Perfect Measurement Sheet with PLM Integration
Crafting the Perfect Measurement Sheet with PLM Integration
 
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
Facemoji Keyboard released its 2023 State of Emoji report, outlining the most...
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
iGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by SkilrockiGaming Platform & Lottery Solutions by Skilrock
iGaming Platform & Lottery Solutions by Skilrock
 
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
Abortion ^Clinic ^%[+971588192166''] Abortion Pill Al Ain (?@?) Abortion Pill...
 
Using IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New ZealandUsing IESVE for Room Loads Analysis - Australia & New Zealand
Using IESVE for Room Loads Analysis - Australia & New Zealand
 
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
A Python-based approach to data loading in TM1 - Using Airflow as an ETL for TM1
 
Agnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in KrakówAgnieszka Andrzejewska - BIM School Course in Kraków
Agnieszka Andrzejewska - BIM School Course in Kraków
 
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
How Does XfilesPro Ensure Security While Sharing Documents in Salesforce?
 
Breaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdfBreaking the Code : A Guide to WhatsApp Business API.pdf
Breaking the Code : A Guide to WhatsApp Business API.pdf
 
Advanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should KnowAdvanced Flow Concepts Every Developer Should Know
Advanced Flow Concepts Every Developer Should Know
 
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
AI/ML Infra Meetup | Improve Speed and GPU Utilization for Model Training & S...
 

The Gremlin Graph Traversal Language

  • 1. The Gremlin Graph Traversal Language Marko A. Rodriguez and Daniel Kuppitz http://tinkerpop.incubator.apache.org
  • 2. user movie categoryoccupation occupation rated category name:String gender:[M,F] age:integer name:String year:integer name:String stars:[1,2,3,4,5] http://grouplens.org/datasets/movielens/ MovieLens Dataset
  • 3. user |Vuser| = 6040 |Vmovie| = 3883 movie |Vcategory| = 18 category |Voccupation| = 21 occupation occupation |Eoccupation| = 6040 rated |Erated| = 1000209 category |Ecategory| = 6408 name:String gender:[M,F] age:integer name:String year:integer name:String stars:[1,2,3,4,5] http://grouplens.org/datasets/movielens/ G = (V, E) MovieLens Dataset
  • 5. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin>
  • 6. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> Gremlin-Java8 Gremlin-Groovy* Gremlin-Scala Gremlin-Clojure Gremlin-JavaScript Gremlin-Python Gremlin-PHP ...
  • 7. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> "Create a new TinkerGraph."
  • 8. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> "Create a new TinkerGraph." G = (V = ∅, E = ∅) G The graph is a set of vertices and edges V The set of vertices in the graph E The set of edges in the graph ∅ The empty set -- no elements
  • 9. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> "Create a new TinkerGraph." G = (V = ∅, E = ∅) TitanGraph.open(…) Neo4jGraph.open(…) OrientGraph.open(…) SqlgGraph.open(…) HadoopGraph.open(…) GiraphGraphComputer SparkGraphComputer ElasticGraph.open(…) ...
  • 10. G = (V = ∅, E ⊆ (V × V )) ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> "Load the MovieLens dataset into the newly created TinkerGraph." Set A is a subset of (or equal to) set B The set of all ordered pairs of vertices (directed binary edges) A ⊆ B (V × V )
  • 11. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> "Create a graph traversal source for spawning graph traversals over the MovieLens graph."
  • 12. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> "Count the number of vertices in the graph." |V | = 9962
  • 13. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> "Count the number of vertices in the graph." |V | = 9962 Vertex map 9962 reducing barrier Long seed=0 value=seed binary operator: value -> value+1 count() { "m any-to-one"
  • 14. Edge map 1012657 reducing barrier Long |E| = 1012657 ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> g.E().count() ==>1012657 gremlin> "Count the number of edges in the graph." count() { "m any-to-one"
  • 15. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> g.E().count() ==>1012657 gremlin> g.V().label().groupCount() ==>[occupation:21, movie:3883, category:18, user:6040] gremlin> "For each vertex in the graph, emit its label, then group and count each distinct label." user user movie category ... Vertex String Map<String,Long> user user movie category map map reducing barrier [ occupation=21, movie=3883, category=18, user=6040 ] label() groupCount(){"one-to-one" "many-to-one"
  • 16. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> g.E().count() ==>1012657 gremlin> g.V().label().groupCount() ==>[occupation:21, movie:3883, category:18, user:6040] gremlin> g.E().hasLabel('rated').values('stars').mean() ==>3.581564453029317 gremlin> "For each rated-edge in the graph, emit its stars property value and compute the average value."
  • 17. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> g.E().count() ==>1012657 gremlin> g.V().label().groupCount() ==>[occupation:21, movie:3883, category:18, user:6040] gremlin> g.E().hasLabel('rated').values('stars').mean() ==>3.581564453029317 gremlin> g.V().hasLabel('user').map(outE('rated').count()).max() ==>2314 gremlin> "What is the maximum number of movies a single user rated?"
  • 18. ~/tinkerpop3$ bin/gremlin.sh ,,,/ (o o) -----oOOo-(3)-oOOo----- plugin activated: tinkerpop.server plugin activated: tinkerpop.utilities plugin activated: tinkerpop.tinkergraph gremlin> graph = TinkerGraph.open() ==>tinkergraph[vertices:0 edges:0] gremlin> graph.io(gryo()).readGraph('/tmp/movie-lens.kryo') ==>null gremlin> g = graph.traversal() ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> g.V().count() ==>9962 gremlin> g.E().count() ==>1012657 gremlin> g.V().label().groupCount() ==>[occupation:21, movie:3883, category:18, user:6040] gremlin> g.E().hasLabel('rated').values('stars').mean() ==>3.581564453029317 gremlin> g.V().hasLabel('user').map(outE('rated').count()).max() ==>2314 gremlin> g.V().hasLabel('movie').values('year').min() ==>1919 gremlin> "What year was the oldest movie made?"
  • 19. gremlin> g.V().hasLabel('category').values('name') ==>Animation ==>Children's ==>Comedy ==>Adventure ==>Fantasy ==>Romance ==>Drama ==>Action ==>Crime ==>Thriller ==>Horror ==>Sci-Fi ==>Documentary ==>War ==>Musical ==>Mystery ==>Film-Noir ==>Western "For each vertex that is labeled 'category,' emit the name property value of that vertex." category user user movie category Vertex category category category category category categorycategory category Vertex Animation Children's Comedy Adventure Western ... String filter map hasLabel('category') values('name') "one-to-[one-or-none]" "one-to-one"
  • 20. gremlin> g.V().hasLabel('category').as('a','b'). select('a','b'). by('name'). by(inE('category').count()) "For each category vertex, emit a map of its name and the number of movies it represents."
  • 21. hasLabelcategory : V ∗ → V ∗ gremlin> g.V().hasLabel('category').as('a','b'). select('a','b'). by('name'). by(inE('category').count()) "For each category vertex, emit a map of its name and the number of movies it represents." V : G → V ∗ asa,b : V ∗ → (V × V )∗ G The set of all graphs f : A → B The function f maps values of type A to values of type B A∗ A stream of values of type A (A × B) The set of all pairs of values from A and B (cross product) N The set of all natural numbers (1, 2, 3, 4, …) The set of all strings (a, b, aa, ab, bb, …) selecta,b : (V × V )∗ → a valuesname : V ∗ → S b (inEcategory : V ∗ → E∗ ) ◦ (count : E∗ → N) → (S × N)∗ S Σ∗ typically denoted
  • 22. gremlin> g.V().hasLabel('category').as('a','b'). select('a','b'). by('name'). by(inE('category').count()) ==>[a:Animation, b:105] ==>[a:Children's, b:251] ==>[a:Comedy, b:1200] ==>[a:Adventure, b:283] ==>[a:Fantasy, b:68] ==>[a:Romance, b:471] ==>[a:Drama, b:1603] ==>[a:Action, b:503] ==>[a:Crime, b:211] ==>[a:Thriller, b:492] ==>[a:Horror, b:343] ==>[a:Sci-Fi, b:276] ==>[a:Documentary, b:127] ==>[a:War, b:143] ==>[a:Musical, b:114] ==>[a:Mystery, b:106] ==>[a:Film-Noir, b:44] ==>[a:Western, b:68] "For each category vertex, emit a map of its name and the number of movies it represents." category user user movie category Vertex category category category category category categorycategory category Vertex [a:Animation, b:105] [a:Children's, b:251] [a:Comedy, b:1200] [a:Adventure, b:283] … [a:Western, b:68] Map<String,Long> filter map category name:Animation category category category ... category map map reducing barrier 105 Vertex Edge Long category name:Animation Vertex String map Animationa b map flatMap {"one-to-m any" "one-to-one"
  • 23. gremlin> g.V().hasLabel('movie').as('a','b'). select('a','b'). by('name'). by(inE('rated').values('stars').mean()). order().by(select('b'),decr). limit(10) "For each movie, emit a map of its name and average rating. Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
  • 24. gremlin> g.V().hasLabel('movie').as('a','b'). select('a','b'). by('name'). by(inE('rated').values('stars').mean()). order().by(select('b'),decr). limit(10) ==>[a:Charm's Incidents, b:NaN] ==>[a:Prerokbe Ognja, b:NaN] ==>[a:Leopard Son, The, b:NaN] ==>[a:Bird of Prey, b:NaN] ==>[a:Plutonium Circus, b:NaN] ==>[a:Hustler White, b:NaN] ==>[a:Curtis's Charm, b:NaN] ==>[a:Three Lives and Only One Death, b:NaN] ==>[a:Hoogste tijd, b:NaN] ==>[a:Entertaining Angels: The Dorothy Day Story, b:NaN] category user user movie category Vertex movie movie movie movie movie moviemovie movie Vertex [a:Charm's Incidents, b:NaN] [a:Prerokbe Ognja, b:NaN] [a:Leopard Son, The, b:NaN] [a:Bird of Prey, b:NaN] ... [a:Entertaining Angels, b:NaN] Map<String,Double> filter map movie name:Charm's Incidents map reducing barrier NaN Vertex Edge Double movie name:Charm's Incidents Vertex String map Charm's Incidentsa b map map Integer ... "For each movie, emit a map of its name and average rating. Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)." flatMap
  • 25. gremlin> g.V().hasLabel('movie').as('a','b'). select('a','b'). by('name'). by(coalesce( inE('rated').values('stars'), constant(0)).mean()). order().by(select('b'),decr). limit(10) ==>[a:Lured, b:5.0] ==>[a:One Little Indian, b:5.0] ==>[a:Bittersweet Motel, b:5.0] ==>[a:Gate of Heavenly Peace, The, b:5.0] ==>[a:Follow the Bitch, b:5.0] ==>[a:Schlafes Bruder (Brother of Sleep), b:5.0] ==>[a:Ulysses (Ulisse), b:5.0] ==>[a:Song of Freedom, b:5.0] ==>[a:Smashing Time, b:5.0] ==>[a:Baby, The, b:5.0] "For each movie, get its name and mean rating (or 0 if no ratings). Order by average rating and emit top 10." user user movie category Vertex movie movie movie movie moviemovie movie Vertex Map<String,Double> filter map movie name:Charm's Incidents map map reducing barrier 0.0 Vertex Integer Double movie name:Charm's Incidents Vertex String map Charm's Incidentsa b map 0 [a:Lured, b:5.0] [a:One Little Indian, b:5.0] [a:Bittersweet Motel, b:5.0] [a:Gate of Heavenly Peace, b:5.0] ... [a:Baby, The, b:5.0] Map<String,Double> map [a:Charm's Incidents, b:NaN] [a:Prerokbe Ognja, b:NaN] [a:Leopard Son, The, b:NaN] [a:Bird of Prey, b:NaN] ... [a:Entertaining Angels, b:NaN] collecting barrier
  • 26. gremlin> g.V().hasLabel('movie').as('a','b'). where(inE('rated').count().is(gt(10))). select('a','b'). by('name'). by(inE('rated').values('stars').mean()). order().by(select('b'),decr). limit(10) "For each movie with at least 11 ratings, emit a map of its name and average rating. Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)."
  • 27. gremlin> g.V().hasLabel('movie').as('a','b'). where(inE('rated').count().is(gt(10))). select('a','b'). by('name'). by(inE('rated').values('stars').mean()). order().by(select('b'),decr). limit(10) ==>[a:Sanjuro, b:4.608695652173913] ==>[a:Seven Samurai (The Magnificent Seven), b:4.560509554140127] ==>[a:Shawshank Redemption, The, b:4.554557700942973] ==>[a:Godfather, The, b:4.524966261808367] ==>[a:Close Shave, A, b:4.52054794520548] ==>[a:Usual Suspects, The, b:4.517106001121705] ==>[a:Schindler's List, b:4.510416666666667] ==>[a:Wrong Trousers, The, b:4.507936507936508] ==>[a:Sunset Blvd. (a.k.a. Sunset Boulevard), b:4.491489361702127] ==>[a:Raiders of the Lost Ark, b:4.47772] "For each movie with at least 11 ratings, emit a map of its name and average rating. Sort the maps in decreasing order by their average rating. Emit the first 10 maps (i.e. top 10)." map movie name:Sanjuro rated rated rated ... rated map reducing barrier 4.60 Vertex Edge Double movie name:Sanjuro Vertex String map Sanjuroa b map map Integer user user movie category Vertex movie movie movie movie moviemovie movie Vertex filter movie rated rated rated ... rated reducing barrier Vertex Edge map Long 69 name:Sanjuro filter movie movie movie movie movie Vertex 5 4 … 5 [[a:Sanjuro, b:4.60] [a:Seven Samurai, b:4.56] [a:Shawshank Redemption, b:4.55] [a:Godfather, The, b:4.52] ... [a:Raiders of the Lost Ark, b:4.47] […] […] […] […] … […] Map<String,Double> Map<String,Double> map collecting barrier flatMap flatMap { {
  • 28. gremlin> g.V().hasLabel('movie'). where(inE('rated').count().is(gt(10))). toString() ==>[GraphStep([],vertex), HasStep([~label.eq(movie)]), TraversalFilterStep([ VertexStep(IN,[rated],edge), CountGlobalStep, IsStep(gt(10))])] "What is the execution plan for the traversal prior to compiler optimizations being applied?" V : G → V ∗ hasLabelmovie : V ∗ → V ∗ where : V ∗ → inErated : V ∗ → E∗ count : E∗ → N isgt(10) : N → (N ∪ ∅) → V ∗ "true orfalse"
  • 29. gremlin> g.V().hasLabel('movie'). where(inE('rated').count().is(gt(10))). iterate().toString() ==>[TinkerGraphStep(vertex,[~label.eq(movie)]), TraversalFilterStep([ VertexStep(IN,[rated],edge), RangeGlobalStep(0,11), CountGlobalStep, IsStep(gt(10))])] "What is the execution plan for the traversal after compiler optimizations have been applied?" * TinkerGraphStragegy: Access vendor-specific vertex partition by label. * RangeByIsCountStrategy: Only iterate 1 more than required count. where : V ∗ → inErated : V ∗ → E∗ count : E∗ → N isgt(10) : N → (N ∪ ∅) limit11 : E∗ → E∗ Vlabel=movie : G → V ∗ → V ∗ "true orfalse"
  • 30. gremlin> g.getStrategies() ==>ConjunctionStrategy a.and().b => and(a,b) a.or().b => or(a,b) a.or().b.and().c => or(a,and(b,c)) a.and().b.or().c => or(and(a,b),c) ==>IncidentToAdjacentStrategy a.outE().inV().b => a.out().b ==>AdjacentToIncidentStrategy a.in().count().b => a.inE().count().b a.where(out()).b => a.where(outE()).b a.and(in(),out()).b => a.and(inE(),outE()).b ==>IdentityRemovalStrategy a.identity().b => a.b ==>FilterRankingStrategy a.order().dedup().b => a.dedup().order().b a.and(c,d).has().b => a.has().and(c,d).b a.simplePath().where().b => b.where().simplePath().a ==>MatchPredicateStrategy a.match(c,d).where(e).b => a.match(c,d,e) a.match(has(),c,d).b => a.has().match(c,d).b ==>RangeByIsCountStrategy a.count().is(0) => a.limit(1).count().is(0) ==>TinkerGraphStepStrategy V.has().has().b => V[has,has].b ==>ProfileStrategy a.b.c.profile() => a.profile().b.profile().c.profile() ==>ComputerVerificationStrategy a.order.b => IllegalStateException a.local(out().out()).b => IllegalStateException "What compilation strategies are associated with the graph traversal source?"
  • 32. gremlin> g.V().has('movie','name','Die Hard'). inE('rated').values('stars').mean() ==>4.121848739495798 "What is Die Hard's average rating?" movie movie movie Vertex movie Vertex filter name:Die Hard flatMap rated rated rated ... rated Edge map 3 5 5 … 4 Integer map Double 4.1218 reducing barrier V : G → V ∗ hasLabelmovie : V ∗ → V ∗ hasname=Die Hard : V ∗ → V ∗ inErated : V ∗ → E∗ mean : N∗ → R valuesstars : E∗ → N∗ user user movie user Vertex filter { "one-to-[one-or-none]" "one-to-[one-or-none]" "one-to-many" "one-to-one" "many-to-one"
  • 33. gremlin> g.V().has('movie','name','Die Hard').as('a'). inE('rated').has('stars',5).outV(). where(out('occupation').has('name','programmer')). outE('rated').has('stars',5).inV(). where(neq('a')). groupCount().by('name'). order(local).by(valueDecr). limit(local,10). unfold() // so its not printed on a single line "Which programmers like Die Hard and what other movies do they like? Group and count the movies by their name. Sort the group count map in decreasing order by the count. Clip the map to the top 10 entries and stream out the map's entries (for display purposes)."
  • 34. gremlin> g.V().has('movie','name','Die Hard').as('a'). inE('rated').has('stars',5).outV(). where(out('occupation').has('name','programmer')). outE('rated').has('stars',5).inV(). where(neq('a')). groupCount().by('name'). order(local).by(valueDecr). limit(local,10). unfold() // so its not printed on a single line "Which programmers like Die Hard and what other movies do they like? Group and count the movies by their name. Sort the group count map in decreasing order by the count. Clip the map to the top 10 entries and stream out the map's entries (for display purposes)." user user movie user Vertex movie Vertex filter filter name:Die Hard flatMap rated rated rated ... rated Edge filter rated ... rated Edge map Vertex user user user useruser user Vertex Vertex occupationflatMap Vertex filter rated rated rated ... rated Edge filter rated ... rated Edge map Vertex movie movie moviemovie movie Vertex Vertex user user user flatMap filter movie Vertex filter Vertex movie movie movie map reducing barrier [ Aliens=105, Braveheart=24, … Pulp Fiction=19 ] Map<String,Long> map collecting barrier [ Raider of the Lost Ark=36, Star Wars: Episode V=24, Star Wars: Episode IV=34 … Airplane II: The Sequel=1 ] Map<String,Long> [ Raider of the Lost Ark=36, Star Wars: Episode V=24, Star Wars: Episode IV=34 … Alien=22 ] Map<String,Long> map occupation programmer not Die Hard
  • 35. gremlin> g.V().has('movie','name','Die Hard').as('a'). inE('rated').has('stars',5).outV(). where(out('occupation').has('name','programmer')). outE('rated').has('stars',5).inV(). where(neq('a')). groupCount().by('name'). order(local).by(valueDecr). limit(local,10). unfold() // so its not printed on a single line ==>Raiders of the Lost Ark=36 ==>Star Wars: Episode V - The Empire Strikes Back=36 ==>Star Wars: Episode IV - A New Hope=34 ==>Matrix, The=32 ==>Terminator, The=29 ==>Star Wars: Episode VI - Return of the Jedi=26 ==>Sixth Sense, The=26 ==>Braveheart=24 ==>Aliens=23 ==>Alien=22 gremlin> "Which programmers like Die Hard and what other movies do they like? Group and count the movies by their name. Sort the group count map in decreasing order by the count. Clip the map to the top 10 entries and stream out the map's entries (for display purposes)."
  • 37. "What 80's action movies do 30-something programmers like? Group count the movies by their name and sort the group count map in decreasing order by value. Clip the map to the top 10 and emit the map entries." gremlin> g.V(). match( __.as('a').hasLabel('movie'), __.as('a').out('category').has('name','Action'), __.as('a').has('year',between(1980,1990)), __.as('a').inE('rated').as('b'), __.as('b').has('stars',5), __.as('b').outV().as('c'), __.as('c').out('occupation').has('name','programmer'), __.as('c').has('age',between(30,40))). select('a').groupCount().by('name'). order(local).by(valueDecr). limit(local,10). unfold() // so its not printed on a single line ==>Raiders of the Lost Ark=26 ==>Star Wars: Episode V - The Empire Strikes Back=26 ==>Terminator, The=23 ==>Star Wars: Episode VI - Return of the Jedi=22 ==>Princess Bride, The=19 ==>Aliens=18 ==>Boat, The (Das Boot)=11 ==>Indiana Jones and the Last Crusade=11 ==>Star Trek: The Wrath of Khan=10 ==>Abyss, The=9 gremlin>
  • 38. MatchStep GraphTraversal.match(Traversal... traversalPatterns) x.match( a...b a...c c... or( a...c a...b ) c.repeat(...).b not(c...a) b...count().e c...count().e ).dedup(a,b).y a,b,c,e : once a variable is set, it must hold equal for all patterns c... : "predicate patterns" simply check for the existence of a result or()/and() : nested conjunctive patterns supported repeat(...) : recursive patterns supported not(...) : not'ing of patterns supported count() : barrier patterns supported dedup(a,b) : internal de-duplication of variable values supported x.match().y : possible to go from imperative to declarative, etc. Plug and Play MatchAlgorithms GreedyMatchAlgorithm : try each pattern in the order provided by the user CountMatchAlgorithm : continually re-sort patterns by the cardinality of their set reductions
  • 39. // CountMatchAlgorithm (default) gremlin> clockWithResult(50){ g.V().match( __.as('a').out('rated').as('b'), __.as('a').out('occupation').has('name','farmer')). select('a','b').count().next()} ==>66.31955294 // time in milliseconds ==>2706 // number of results // GreedyMatchAlgorithm gremlin> g = graph.traversal(GraphTraversalSource.build(). with(MatchAlgorithmStrategy.build(). algorithm(MatchStep.GreedyMatchAlgorithm).create())) ==>graphtraversalsource[tinkergraph[vertices:9962 edges:1012657], standard] gremlin> clockWithResult(50){ g.V().match( __.as('a').out('rated').as('b'), __.as('a').out('occupation').has('name','farmer')). select('a','b').count().next()} ==>1902.6290871599997 // time in milliseconds ==>2706 // number of results "Which movies did each farmer rate? -- benchmark CountMatchAlgorithm vs. GreedyMatchAlgorithm." farmermoviesusers 1000209 2706 farmer moviesusers 17 2706
  • 40. gremlin> g.V().hasLabel('movie'). where(inE('rated').count().is(gt(10))). group(). by{((int)(it.value('year') / 10)) * 10}. by(). by(unfold().order(). by(inE('rated').values('stars').mean(),decr). values('name'). limit(1)). order(local).by(keyIncr). unfold() // so its not printed on a single line "What is the most liked movie in each decade?"
  • 41. gremlin> g.V().hasLabel('movie'). where(inE('rated').count().is(gt(10))). group(). by{((int)(it.value('year') / 10)) * 10}. by(). by(unfold().order(). by(inE('rated').values('stars').mean(),decr). values('name'). limit(1)). order(local).by(keyIncr). unfold() // so its not printed on a single line "What is the most liked movie in each decade?" λ λ Nearly every step that takes a traversal argument can also take a lambda. It is recommended that users do not use lambdas as they are not subject to traversal strategy (i.e. compiler) optimization. However, they are useful when no provided step yields the desired computation.
  • 42. gremlin> g.V().hasLabel('movie'). where(inE('rated').count().is(gt(10))). group(). by{((int)(it.value('year') / 10)) * 10}. by(). by(unfold().order(). by(inE('rated').values('stars').mean(),decr). values('name'). limit(1)). order(local).by(keyIncr). unfold() // so its not printed on a single line ==>1910=Daddy Long Legs ==>1920=General, The ==>1930=City Lights ==>1940=Third Man, The ==>1950=Seven Samurai (The Magnificent Seven) ==>1960=Sanjuro ==>1970=Godfather, The ==>1980=Raiders of the Lost Ark ==>1990=Shawshank Redemption, The ==>2000=Almost Famous gremlin> "What is the most liked movie in each decade?"
  • 43. gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties') ==>hadoopgraph[gryoinputformat->gryooutputformat] gremlin> g = graph.traversal(computer(SparkGraphComputer)) ==>graphtraversalsource [hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer] gremlin> "Which movies are most central in the implicit 5-stars graph?"
  • 44. gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties') ==>hadoopgraph[gryoinputformat->gryooutputformat] gremlin> g = graph.traversal(computer(SparkGraphComputer)) ==>graphtraversalsource [hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer] gremlin> g.V().repeat(outE('rated').has('stars', 5).inV(). groupCount('m').by('name'). inE('rated').has('stars', 5).outV()). times(4).cap('m') "Which movies are most central in the implicit 5-stars graph?" user movie user ratedrated m 4x cap('m') repeat(…).times(4) g.V() stars=5 stars=5
  • 45. gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties') ==>hadoopgraph[gryoinputformat->gryooutputformat] gremlin> g = graph.traversal(computer(SparkGraphComputer)) ==>graphtraversalsource [hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer] gremlin> g.V().repeat(outE('rated').has('stars', 5).inV(). groupCount('m').by('name'). inE('rated').has('stars', 5).outV()). times(4).cap('m') ==>Fantasia 2000=2676505178171564 ==>Pale Rider=1369969000295362 ==>Crucible, The=401712993698149 ==>About Adam=37981148456999 ==>Akira=3659939409345918 ... gremlin> "Which movies are most central in the implicit 5-stars graph?"
  • 46. gremlin> graph = HadoopGraph.open('conf/hadoop/movie-lens.properties') ==>hadoopgraph[gryoinputformat->gryooutputformat] gremlin> g = graph.traversal(computer(SparkGraphComputer)) ==>graphtraversalsource [hadoopgraph[gryoinputformat->gryooutputformat], sparkgraphcomputer] gremlin> g.V().repeat(outE('rated').has('stars', 5).inV(). groupCount('m').by('name'). inE('rated').has('stars', 5).outV()). times(4).cap('m') ==>Fantasia 2000=2676505178171564 ==>Pale Rider=1369969000295362 ==>Crucible, The=401712993698149 ==>About Adam=37981148456999 ==>Akira=3659939409345918 ... gremlin> hdfs.ls('output/m') ==>rw-r--r-- daniel supergroup 0 _SUCCESS ==>rw-r--r-- daniel supergroup 245314 part-r-00000 gremlin> hdfs.head('output/m', ObjectWritable).sort {-it.value}.take(10) ==>Star Wars: Episode IV - A New Hope 35405394353105332 ==>American Beauty 31943228282020585 ==>Raiders of the Lost Ark 31224779793238499 ==>Star Wars: Episode V - The Empire Strikes Back 30434677119726223 ==>Godfather, The 30258518523013057 ==>Shawshank Redemption, The 28297717387901031 ==>Schindler's List 27539336654199309 ==>Silence of the Lambs, The 26736276376806173 ==>Fargo 26531050311325270 ==>Matrix, The 26395118239203191 "Which movies are most central in the implicit 5-stars graph?"
  • 47. gremlin> :plugin use tinkerpop.gephi ==>tinkerpop.gephi activated gremlin> :remote connect tinkerpop.gephi ==>Connection to Gephi - http://localhost:8080/workspace0 with stepDelay:1000, startRGBColor:[0.0, 1.0, 0.5], colorToFade:g, colorFadeRate:0.7, startSize: 20.0,sizeDecrementRate:0.33 gremlin>
  • 48. gremlin> :plugin use tinkerpop.gephi ==>tinkerpop.gephi activated gremlin> :remote connect tinkerpop.gephi ==>Connection to Gephi - http://localhost:8080/workspace0 with stepDelay:1000, startRGBColor:[0.0, 1.0, 0.5], colorToFade:g, colorFadeRate:0.7, startSize: 20.0,sizeDecrementRate:0.33 gremlin> :> g.V().hasLabel('user'). order(). by(outE('rated').count(), decr).limit(10).as('a'). local(outE('rated').order(). by('stars', decr). // first by stars by(inV().inE('rated').count(), decr). // then by ratings limit(10)). subgraph('sg').inV().outE('category'). subgraph('sg').select('a').outE('occupation'). subgraph('sg').cap('sg').next() ==>tinkergraph[vertices:82 edges:233] gremlin> "Which users rated the most movies? For each user, display their 10 favorite movies, the categories of those movies, and their occupation. "moviebuffs"
  • 49.