SlideShare a Scribd company logo
1 of 54
Extending Gremlin with
Foundational Steps
2019
Introduction
A Short Explanation of Graphs and Apache TinkerPop
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
What is a Graph?
● A property graph is a collection of vertices and edges
○ A vertex represents entities/domain objects
○ An edge represents a directional relationship between two vertices
○ Vertices and edges have labels and properties
label: person
name: Stephen
label: organization
name: DataStax
label: person
name: Paras
label: employs
since: 2015
label: employs
since: 2016
label: knows
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Apache TinkerPop
● An open source graph computing
framework for both graph databases
(OLTP) and graph analytic systems
(OLAP)
● Provides the Gremlin graph traversal
language
● Exposes an agnostic way by which users
can build graph applications
● Wide industry support to include DataStax
Graph (currently, there are over two dozen
graph systems are TinkerPop-enabled)
Gremlin
The Graph Traversal Language of Apache TinkerPop
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Gremlin is a
functional, data-flow
language that enables
users to succinctly
express complex
traversals on their
application's property
graph.
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
values("name")
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
This query
demonstrates the
three hallmarks of
novice Gremlin usage:
1. Filtering
2. Navigation
3. Simple
Transformation
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
values("name")
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
What skill
tends to
separate the
novice from
the advanced
Gremlin user?
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
The advanced
Gremlin user
can easily
extract data
that they need
from a traversal
in the form that
they want.
Novice to Advanced
A Thin Line Between Novice and Advanced Gremlin with a Customer-360 Style Use Case
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Expanded Example Graph
organizationperson
employs
knows
event
hosts
presents
attends hosts
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Expanded Example Graph
g.addV('person').property('name','stephen').property('timeZone','EST').as('s').
addV('person').property('name','paras').property('timeZone','EST').as('p').
addV('organization').property('name','datastax').
property('city','santa clara').property('state','CA').as('ds').
addV('event').property('name','DataStax Accelerate').
property('presentation','Extending Gremlin with Foundational Steps').
property('year','2019').property('attendees',100).as('da').
addV('event').property('name','Cassandra & DataStax DC Meetup').
property('presentation','Gremlin Queries with DataStax Enterprise Graph').
property('year','2017').property('attendees',35).as('dm0').
addE('knows').from('s').to('p').
addE('employs').from('ds').to('p').property('since',2016).
addE('employs').from('ds').to('s').property('since',2015).
addE('attends').from('s').to('da').
addE('presents').from('s').to('da').
addE('hosts').from('ds').to('da').
addE('attends').from('s').to('dm0').
addE('presents').from('s').to('dm0').
addE('hosts').from('p').to('dm0').iterate()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Consider these ego-
centric traversals that
use purely novice-
level Gremlin (i.e.
filtering, navigation,
simple
transformations) to
gather information
from the local
subgraph about
“stephen”.
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
valueMap("name","timeZone")
“Who has employed Stephen?”
g.V().has("person","name","stephen").
inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state")
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
outE("attends").
count()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
valueMap("name","timeZone")
“Who has employed Stephen?”
g.V().has("person","name","stephen").
inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state")
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
outE("attends").
count()
JSON
[{
"name": ["paras"],
"timeZone":
["EST"]
}]
JSON
[{
"city": ["santa
clara"],
"name": ["datastax"],
"state": ["CA"]
}]
JSON [2]
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“How many events did Stephen attend?”
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
What does an
application need in terms
of these individual
results?
1. A single traversal
instead of multiple
traversals
2. Simplified collections -
flattened property
values rather than
lists
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Steps for Collection Construction
● Lists
○ store()
○ aggregate()
○ fold()
○ path()
○ union()
● Maps
○ group()/groupCount()
○ project()
○ select()
○ valueMap()/propertyMap()
Collection Manipulation
● unfold()
● range()
● limit()
● tail()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
valueMap("name","timeZone")
“Who has employed Stephen?”
g.V().has("person","name","stephen").
inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state")
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
outE("attends").
count()
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
Note that...
The traversals have the same
starting filter and thus begin with
the same vertex. Each traverses
away from that vertex to gather
data about “stephen”
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
g.V().has("person","name","stephen").
out("knows").
valueMap("name","timeZone")
“Who has employed Stephen?”
g.V().has("person","name","stephen").
inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state")
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
outE("attends").
count()
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
Note that...
The desired result is a Map with
user defined keys each holding a
result that contain data gathered
by traversing away from
“stephen”.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Collection Manipulation
● unfold()
● range()
● limit()
● tail()
Steps for Collection Construction
● Lists
○ store()
○ aggregate()
○ fold()
○ path()
○ union()
● Maps
○ group()/groupCount()
○ project()
○ select()
○ valueMap()/propertyMap()
Use project() when the Map
keys are known/static and
when features of the current
traverser are meant to be
represented for each key.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.V().has("person","name","stephen")
==>v[0]
gremlin> g.V().has("person","name","stephen").
......1> project("colleagues", "employers", "eventsAttended")
==>[colleagues:v[0],employers:v[0],eventsAttended:v[0]]
gremlin> g.V().has("person","name","stephen").
......1> project("colleagues", "employers", "eventsAttended").
......2> by(fold())
==>[colleagues:[v[0]],employers:[v[0]],eventsAttended:[v[0]]]
Use of project()
project() accepts a by()
modulator for each specified
key which is responsible for
the transformation to apply to
v[0] for that key.
1
2
3
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.V().has("person","name","stephen").
......1> outE("attends").
......2> count()
==>2
gremlin> g.V().has("person","name","stephen").
......1> project("colleagues", "employers", "eventsAttended").
......2> by(fold()).
......3> by(fold()).
......4> by(outE("attends").count())
==>[colleagues:[v[0]],employers:[v[0]],eventsAttended:2]
Use of project() - “eventsAttended” key
Projects v[0] to
“eventsAttended” key using
the “How many events did
Stephen attend?” traversal.
“How many events did Stephen attend?”
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.V().has("person","name","stephen").
......1> out("knows").
......2> valueMap("name","timeZone")
==>[name:[paras],timeZone:[EST]]
gremlin> g.V().has("person","name","stephen").
......1> out("knows").
......2> valueMap("name","timeZone").
......3> by(unfold())
==>[name:paras,timeZone:EST]
Use of project() - “colleagues” key
unfold() deconstructs a
List to a stream and by()
only grabs the first object of
the child traversal. The effect
is to unwrap the embedded
List.
“Who does Stephen know?”
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.V().has("person","name","stephen").
......1> out("knows").
......2> valueMap("name","timeZone").
......3> by(unfold())
==>[name:paras,timeZone:EST]
gremlin> g.V().has("person","name","stephen").
......1> project("colleagues", "employers", "eventsAttended").
......2> by(out("knows").valueMap("name","timeZone").by(unfold()).fold()).
......3> by(fold()).
......4> by(outE("attends").count())
==>[colleagues:[[name:paras,timeZone:EST]],employers:[v[0]],eventsAttended:2]
Use of project() - “colleagues” key
“Who does Stephen know?”
Projects v[0] to “colleagues”
key using the “Who does
Stephen know?” traversal.
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.V().has("person","name","stephen").
......1> inE("employs").
......2> order().by("since",desc).
......3> outV().
......4> valueMap("name","city","state").
......5> by(unfold())
==>[city:santa clara,name:datastax,state:CA]
gremlin> g.V().has("person","name","stephen").
......1> project("colleagues","employers","eventsAttended").
......2> by(out("knows").valueMap("name","timeZone").by(unfold()).fold()).
......3> by(inE("employs").
......4> order().by("since",desc).
......5> outV().
......6> valueMap("name","city","state").
......7> by(unfold()).
......8> fold()).
......9> by(outE("attends").count()).next()
==>colleagues=[{name=paras, timeZone=EST}]
==>employers=[{city=santa clara, name=datastax, state=CA}]
==>eventsAttended=2]
Use of project() - “employers” key
“Who has employed Stephen?”
Projects v[0] to “employers”
key using the “Who has
employed Stephen?” traversal.
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
valueMap("name","timeZone").
by(unfold()).
fold()).
by(inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state").
by(unfold()).
fold()).
by(outE("attends").count())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
Gremlin DSLs
Building Domain Specific Languages (DSLs) with Gremlin
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
A Gremlin-
based DSL
allows
traversals to be
written in the
language of the
application
domain.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Benefits of Gremlin DSLs
● Hide traversal complexity
● Improve Gremlin testability
● Improve code readability
● Improve code maintainability and reusability
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Gremlin DSL
concepts can
apply to an
application
domain, but also
to fundamental
extension of the
graph domain.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
“Who does Stephen know?”
“Who has employed Stephen?”
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
valueMap("name","timeZone").
by(unfold()).
fold()).
by(inE("employs").
order().by("since",desc).
outV().
valueMap("name","city","state").
by(unfold()).
fold()).
by(outE("attends").count())
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Steps for Collection Construction
● Lists
○ store()
○ aggregate()
○ fold()
○ path()
○ union()
● Maps
○ group()/groupCount()
○ project()
○ select()
○ valueMap()/propertyMap()
○ simpleMap()
Collection Manipulation
● unfold()
● range()
● limit()
● tail()
This looks like
a helpful step!
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl
● TinkerPop provides a Java annotation processor in gremlin-
core to help build DSLs.
● The @GremlinDsl annotation is applied to an interface that
extends the GraphTraversal interface with new steps.
● The annotation processor then generates the appropriate
boilerplate code and includes the new step.
● While this topic is discussed in Java, DSLs can be built in any
Gremlin Language Variant.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - simpleMap()
@GremlinDsl()
public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) {
return valueMap(keys).by(__.unfold());
}
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - Usage
DseSession session = DseSession.builder().build();
RemoteConnection conn = DseGraph.remoteConnectionBuilder(session).build();
FoundationTraversalSource g = traversal(FoundationTraversalSource.class).
withRemote(conn);
Map<String,Object> m = g.V().has("person","name","stephen").simpleMap().next();
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
“Who does Stephen know?”
“Who has employed Stephen?”
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(outE("attends").count())
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa
clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": 2
}
“Who does Stephen know?”
“Who has employed Stephen?”
“How many events did Stephen attend?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(outE("attends").count())
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold()
g.V().has("person","name","stephen").
out("attends").
order().by("attendees",desc).
simpleMap("name","presentation")
g.V().has("person","name","stephen").
out("attends").
order().by("attendees",desc).
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))
1
1
2 2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
out("attends").
order().by("attendees",desc).
map(union(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
unfold().
group().by(keys).by(select(values))).
fold()
Merging
two Maps!
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Steps for Collection Construction
● Lists
○ store()
○ aggregate()
○ fold()
○ path()
○ union()
● Maps
○ group()/groupCount()
○ project()
○ select()
○ valueMap()/propertyMap()
○ singleMap()
Collection Manipulation
● unfold()
● range()
● limit()
● tail()
● merge()
● partition()
● interleave()
● zip()
These look like
helpful steps!
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - merge()
@GremlinDsl()
public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) {
return valueMap(keys).by(__.unfold());
}
default GraphTraversal<S, Map> merge(Traversal... maps) {
return map(__.union(maps).
unfold().
group().
by(keys).
by(__.select(values)));
}
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
merge(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
out("attends").
order().by("attendees",desc).
merge(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
fold()
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
“Who does Stephen know?”
“Who has employed Stephen?”
“What events has Stephen attended and who were the presenters/hosts?”
g.V().has("person","name","stephen").
project("colleagues","employers","eventsAttended").
by(out("knows").
simpleMap("name","timeZone").
fold()).
by(inE("employs").
order().by("since",desc).
outV().
simpleMap("name","city","state").
fold()).
by(out("attends").
order().by("attendees",desc).
merge(simpleMap("name","presentation"),
inE("presents","hosts").
group().
by(label).
by(outV().values("name"))).
fold())
{
"colleagues": [{
"name": "paras",
"timeZone": "EST"
}],
"employers": [{
"city": "santa clara",
"name": "datastax",
"state": "CA"
}],
"eventsAttended": [{
"presentation": "Extending Gremlin...",
"hosts": "datastax",
"name": "DataStax Accelerate",
"presents": "stephen"
}, {
"presentation": "Gremlin Queries...",
"hosts": "paras",
"name": "Cassandra & DataStax DC
Meetup",
"presents": "stephen"
}]
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - partition()
@GremlinDsl()
public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) {
return valueMap(keys).by(__.unfold());
}
...
default GraphTraversal<S, List<Object>> partition(int size) {
return emit().
until(__.not(__.unfold())).
repeat(__.skip(local,size)).
filter(__.unfold()).
limit(local,size);
}
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.inject([1,2,3,4,5,6])
==>[1,2,3,4,5,6]
gremlin> g.inject([1,2,3,4,5,6]).partition(2)
==>[1,2]
==>[3,4]
==>[5,6]
gremlin> g.inject([1,2,3,4,5,6]).partition(3)
==>[1,2,3]
==>[4,5,6]
Use of partition()
1
2
3
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - interleave()
@GremlinDsl()
public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) {
return valueMap(keys).by(__.unfold());
}
...
default GraphTraversal<S,Map<Object,Object>> interleave() {
return index().
unfold().
order().
by(__.tail(local)).
limit(local,1);
}
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.inject([1,2,3],['a','b','c'],[7,8,9]).interleave()
==>1
==>a
==>7
==>2
==>b
==>8
==>3
==>c
==>9
gremlin> g.inject([1,2,3],['a','b','c'],[7,8,9]).interleave().fold().partition(3)
==>[1,a,7]
==>[2,b,8]
==>[3,c,9]
Use of interleave()
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
@GremlinDsl - zip()
@GremlinDsl()
public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> {
default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) {
return valueMap(keys).by(__.unfold());
}
...
default GraphTraversal<S,Map<Object,Object>> zip() {
return ((FoundationTraversal) interleave()).
fold().
partition(2).
group().
by(__.limit(local,1)).
by(__.skip(local,1).unfold());
}
}
Build more complex DSL
steps based on other
lower level DSL steps.
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.inject(['a','b','c'],[4,5,6])
==>[a,b,c]
==>[4,5,6]
gremlin> g.inject(['a','b','c'],[4,5,6]).zip()
==>[a:4,b:5,c:6]
Use of zip()
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
gremlin> g.inject(['a','b','c'],[4,5,6]).zip()
==>[a:4,b:5,c:6]
gremlin> g.inject(['a','b','c'],[4,5,6]).
......1> index().
......2> unfold().
......3> order().
......4> by(tail(local)).
......5> limit(local,1).fold().
......6> emit().
......7> until(__.not(unfold())).
......8> repeat(skip(local,2)).
......9> filter(unfold()).
.....10> limit(local,2).
.....11> group().
.....12> by(limit(local,1)).
.....13> by(skip(local,1).unfold())
==>[a:4,b:5,c:6]
Use of zip()
1
2
© DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved.
Gremlin DSL
Resources
1. DSL Introduction (Java
oriented) -
https://s.apache.org/bipK
2. DSL design guidelines
(Python oriented) -
https://s.apache.org/1xiv
3. DSL pattern for “enrichment”
(.NET oriented) -
https://s.apache.org/knOS
4. DSL sample code -
https://s.apache.org/UNiz

More Related Content

What's hot

What's hot (20)

Open Policy Agent Deep Dive Seattle 2018
Open Policy Agent Deep Dive Seattle 2018Open Policy Agent Deep Dive Seattle 2018
Open Policy Agent Deep Dive Seattle 2018
 
Rego Deep Dive
Rego Deep DiveRego Deep Dive
Rego Deep Dive
 
Scaling containers with KEDA
Scaling containers with KEDAScaling containers with KEDA
Scaling containers with KEDA
 
Modern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with NomadModern Scheduling for Modern Applications with Nomad
Modern Scheduling for Modern Applications with Nomad
 
Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)Reinventing the Transaction Script (NDC London 2020)
Reinventing the Transaction Script (NDC London 2020)
 
[네전따] 네트워크 엔지니어에게 쿠버네티스는 어떤 의미일까요
[네전따] 네트워크 엔지니어에게 쿠버네티스는 어떤 의미일까요[네전따] 네트워크 엔지니어에게 쿠버네티스는 어떤 의미일까요
[네전따] 네트워크 엔지니어에게 쿠버네티스는 어떤 의미일까요
 
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
Deep Dive into Spark SQL with Advanced Performance Tuning with Xiao Li & Wenc...
 
A NOSQL Overview And The Benefits Of Graph Databases (nosql east 2009)
A NOSQL Overview And The Benefits Of Graph Databases (nosql east 2009)A NOSQL Overview And The Benefits Of Graph Databases (nosql east 2009)
A NOSQL Overview And The Benefits Of Graph Databases (nosql east 2009)
 
Designing and Implementing a Real-time Data Lake with Dynamically Changing Sc...
Designing and Implementing a Real-time Data Lake with Dynamically Changing Sc...Designing and Implementing a Real-time Data Lake with Dynamically Changing Sc...
Designing and Implementing a Real-time Data Lake with Dynamically Changing Sc...
 
Traversing Graph Databases with Gremlin
Traversing Graph Databases with GremlinTraversing Graph Databases with Gremlin
Traversing Graph Databases with Gremlin
 
JSON-LD and MongoDB
JSON-LD and MongoDBJSON-LD and MongoDB
JSON-LD and MongoDB
 
Final terraform
Final terraformFinal terraform
Final terraform
 
02 terraform core concepts
02 terraform core concepts02 terraform core concepts
02 terraform core concepts
 
Terraform
TerraformTerraform
Terraform
 
Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...
Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...
Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...
 
Spring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCodeSpring Boot + React + Gradle in VSCode
Spring Boot + React + Gradle in VSCode
 
Enhancing Network and Runtime Security with Cilium and Tetragon by Raymond De...
Enhancing Network and Runtime Security with Cilium and Tetragon by Raymond De...Enhancing Network and Runtime Security with Cilium and Tetragon by Raymond De...
Enhancing Network and Runtime Security with Cilium and Tetragon by Raymond De...
 
Regular Expression
Regular ExpressionRegular Expression
Regular Expression
 
Everything You Need To Know About Persistent Storage in Kubernetes
Everything You Need To Know About Persistent Storage in KubernetesEverything You Need To Know About Persistent Storage in Kubernetes
Everything You Need To Know About Persistent Storage in Kubernetes
 
Pipeline oriented programming
Pipeline oriented programmingPipeline oriented programming
Pipeline oriented programming
 

Similar to Extending Gremlin with Foundational Steps

Bridging Structured and Unstructred Data with Apache Hadoop and Vertica
Bridging Structured and Unstructred Data with Apache Hadoop and VerticaBridging Structured and Unstructred Data with Apache Hadoop and Vertica
Bridging Structured and Unstructred Data with Apache Hadoop and Vertica
Steve Watt
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
parag978978
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyas
rsnarayanan
 

Similar to Extending Gremlin with Foundational Steps (20)

Bridging Structured and Unstructred Data with Apache Hadoop and Vertica
Bridging Structured and Unstructred Data with Apache Hadoop and VerticaBridging Structured and Unstructred Data with Apache Hadoop and Vertica
Bridging Structured and Unstructred Data with Apache Hadoop and Vertica
 
Googlevis examples
Googlevis examplesGooglevis examples
Googlevis examples
 
Flink Forward San Francisco 2018: Seth Wiesman - "Testing Stateful Streaming ...
Flink Forward San Francisco 2018: Seth Wiesman - "Testing Stateful Streaming ...Flink Forward San Francisco 2018: Seth Wiesman - "Testing Stateful Streaming ...
Flink Forward San Francisco 2018: Seth Wiesman - "Testing Stateful Streaming ...
 
Using a mobile phone as a therapist - Superweek 2018
Using a mobile phone as a therapist - Superweek 2018Using a mobile phone as a therapist - Superweek 2018
Using a mobile phone as a therapist - Superweek 2018
 
An Interactive Introduction To R (Programming Language For Statistics)
An Interactive Introduction To R (Programming Language For Statistics)An Interactive Introduction To R (Programming Language For Statistics)
An Interactive Introduction To R (Programming Language For Statistics)
 
Go Programming Patterns
Go Programming PatternsGo Programming Patterns
Go Programming Patterns
 
Introduction to R
Introduction to RIntroduction to R
Introduction to R
 
Big Data Analytics with Scala at SCALA.IO 2013
Big Data Analytics with Scala at SCALA.IO 2013Big Data Analytics with Scala at SCALA.IO 2013
Big Data Analytics with Scala at SCALA.IO 2013
 
Scala 2 + 2 > 4
Scala 2 + 2 > 4Scala 2 + 2 > 4
Scala 2 + 2 > 4
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
GraphFrames Access Methods in DSE Graph
GraphFrames Access Methods in DSE GraphGraphFrames Access Methods in DSE Graph
GraphFrames Access Methods in DSE Graph
 
Aerospike Nested CDTs - Meetup Dec 2019
Aerospike Nested CDTs - Meetup Dec 2019Aerospike Nested CDTs - Meetup Dec 2019
Aerospike Nested CDTs - Meetup Dec 2019
 
Move your data (Hans Rosling style) with googleVis + 1 line of R code
Move your data (Hans Rosling style) with googleVis + 1 line of R codeMove your data (Hans Rosling style) with googleVis + 1 line of R code
Move your data (Hans Rosling style) with googleVis + 1 line of R code
 
LSPE Meetup talk on Graphite
LSPE Meetup talk on GraphiteLSPE Meetup talk on Graphite
LSPE Meetup talk on Graphite
 
Linq Sanjay Vyas
Linq   Sanjay VyasLinq   Sanjay Vyas
Linq Sanjay Vyas
 
Chris Mc Glothen Sql Portfolio
Chris Mc Glothen Sql PortfolioChris Mc Glothen Sql Portfolio
Chris Mc Glothen Sql Portfolio
 
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
All About JSON and ClickHouse - Tips, Tricks and New Features-2022-07-26-FINA...
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
 
Coding Ajax
Coding AjaxCoding Ajax
Coding Ajax
 

Recently uploaded

Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
panagenda
 

Recently uploaded (20)

Generative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdfGenerative AI Use Cases and Applications.pdf
Generative AI Use Cases and Applications.pdf
 
Overview of Hyperledger Foundation
Overview of Hyperledger FoundationOverview of Hyperledger Foundation
Overview of Hyperledger Foundation
 
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
Easier, Faster, and More Powerful – Alles Neu macht der Mai -Wir durchleuchte...
 
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
Secure Zero Touch enabled Edge compute with Dell NativeEdge via FDO _ Brad at...
 
State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!State of the Smart Building Startup Landscape 2024!
State of the Smart Building Startup Landscape 2024!
 
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
Event-Driven Architecture Masterclass: Engineering a Robust, High-performance...
 
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
Event-Driven Architecture Masterclass: Integrating Distributed Data Stores Ac...
 
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdfWhere to Learn More About FDO _ Richard at FIDO Alliance.pdf
Where to Learn More About FDO _ Richard at FIDO Alliance.pdf
 
Design Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptxDesign Guidelines for Passkeys 2024.pptx
Design Guidelines for Passkeys 2024.pptx
 
Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024Extensible Python: Robustness through Addition - PyCon 2024
Extensible Python: Robustness through Addition - PyCon 2024
 
WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024WebRTC and SIP not just audio and video @ OpenSIPS 2024
WebRTC and SIP not just audio and video @ OpenSIPS 2024
 
The Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and InsightThe Zero-ETL Approach: Enhancing Data Agility and Insight
The Zero-ETL Approach: Enhancing Data Agility and Insight
 
Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024Long journey of Ruby Standard library at RubyKaigi 2024
Long journey of Ruby Standard library at RubyKaigi 2024
 
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdfLinux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
Linux Foundation Edge _ Overview of FDO Software Components _ Randy at Intel.pdf
 
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdfIntroduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
Introduction to FDO and How It works Applications _ Richard at FIDO Alliance.pdf
 
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdfSimplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
Simplified FDO Manufacturing Flow with TPMs _ Liam at Infineon.pdf
 
AI mind or machine power point presentation
AI mind or machine power point presentationAI mind or machine power point presentation
AI mind or machine power point presentation
 
Portal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russePortal Kombat : extension du réseau de propagande russe
Portal Kombat : extension du réseau de propagande russe
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
Working together SRE & Platform Engineering
Working together SRE & Platform EngineeringWorking together SRE & Platform Engineering
Working together SRE & Platform Engineering
 

Extending Gremlin with Foundational Steps

  • 2.
  • 3. Introduction A Short Explanation of Graphs and Apache TinkerPop
  • 4. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. What is a Graph? ● A property graph is a collection of vertices and edges ○ A vertex represents entities/domain objects ○ An edge represents a directional relationship between two vertices ○ Vertices and edges have labels and properties label: person name: Stephen label: organization name: DataStax label: person name: Paras label: employs since: 2015 label: employs since: 2016 label: knows
  • 5. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Apache TinkerPop ● An open source graph computing framework for both graph databases (OLTP) and graph analytic systems (OLAP) ● Provides the Gremlin graph traversal language ● Exposes an agnostic way by which users can build graph applications ● Wide industry support to include DataStax Graph (currently, there are over two dozen graph systems are TinkerPop-enabled)
  • 6. Gremlin The Graph Traversal Language of Apache TinkerPop
  • 7. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Gremlin is a functional, data-flow language that enables users to succinctly express complex traversals on their application's property graph. “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). values("name")
  • 8. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. This query demonstrates the three hallmarks of novice Gremlin usage: 1. Filtering 2. Navigation 3. Simple Transformation “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). values("name")
  • 9. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. What skill tends to separate the novice from the advanced Gremlin user?
  • 10. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. The advanced Gremlin user can easily extract data that they need from a traversal in the form that they want.
  • 11. Novice to Advanced A Thin Line Between Novice and Advanced Gremlin with a Customer-360 Style Use Case
  • 12. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Expanded Example Graph organizationperson employs knows event hosts presents attends hosts
  • 13. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Expanded Example Graph g.addV('person').property('name','stephen').property('timeZone','EST').as('s'). addV('person').property('name','paras').property('timeZone','EST').as('p'). addV('organization').property('name','datastax'). property('city','santa clara').property('state','CA').as('ds'). addV('event').property('name','DataStax Accelerate'). property('presentation','Extending Gremlin with Foundational Steps'). property('year','2019').property('attendees',100).as('da'). addV('event').property('name','Cassandra & DataStax DC Meetup'). property('presentation','Gremlin Queries with DataStax Enterprise Graph'). property('year','2017').property('attendees',35).as('dm0'). addE('knows').from('s').to('p'). addE('employs').from('ds').to('p').property('since',2016). addE('employs').from('ds').to('s').property('since',2015). addE('attends').from('s').to('da'). addE('presents').from('s').to('da'). addE('hosts').from('ds').to('da'). addE('attends').from('s').to('dm0'). addE('presents').from('s').to('dm0'). addE('hosts').from('p').to('dm0').iterate()
  • 14. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Consider these ego- centric traversals that use purely novice- level Gremlin (i.e. filtering, navigation, simple transformations) to gather information from the local subgraph about “stephen”. “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). valueMap("name","timeZone") “Who has employed Stephen?” g.V().has("person","name","stephen"). inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state") “How many events did Stephen attend?” g.V().has("person","name","stephen"). outE("attends"). count()
  • 15. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). valueMap("name","timeZone") “Who has employed Stephen?” g.V().has("person","name","stephen"). inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state") “How many events did Stephen attend?” g.V().has("person","name","stephen"). outE("attends"). count() JSON [{ "name": ["paras"], "timeZone": ["EST"] }] JSON [{ "city": ["santa clara"], "name": ["datastax"], "state": ["CA"] }] JSON [2]
  • 16. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “How many events did Stephen attend?” { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } What does an application need in terms of these individual results? 1. A single traversal instead of multiple traversals 2. Simplified collections - flattened property values rather than lists
  • 17. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Steps for Collection Construction ● Lists ○ store() ○ aggregate() ○ fold() ○ path() ○ union() ● Maps ○ group()/groupCount() ○ project() ○ select() ○ valueMap()/propertyMap() Collection Manipulation ● unfold() ● range() ● limit() ● tail()
  • 18. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). valueMap("name","timeZone") “Who has employed Stephen?” g.V().has("person","name","stephen"). inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state") “How many events did Stephen attend?” g.V().has("person","name","stephen"). outE("attends"). count() { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } Note that... The traversals have the same starting filter and thus begin with the same vertex. Each traverses away from that vertex to gather data about “stephen”
  • 19. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” g.V().has("person","name","stephen"). out("knows"). valueMap("name","timeZone") “Who has employed Stephen?” g.V().has("person","name","stephen"). inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state") “How many events did Stephen attend?” g.V().has("person","name","stephen"). outE("attends"). count() { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } Note that... The desired result is a Map with user defined keys each holding a result that contain data gathered by traversing away from “stephen”.
  • 20. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Collection Manipulation ● unfold() ● range() ● limit() ● tail() Steps for Collection Construction ● Lists ○ store() ○ aggregate() ○ fold() ○ path() ○ union() ● Maps ○ group()/groupCount() ○ project() ○ select() ○ valueMap()/propertyMap() Use project() when the Map keys are known/static and when features of the current traverser are meant to be represented for each key.
  • 21. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.V().has("person","name","stephen") ==>v[0] gremlin> g.V().has("person","name","stephen"). ......1> project("colleagues", "employers", "eventsAttended") ==>[colleagues:v[0],employers:v[0],eventsAttended:v[0]] gremlin> g.V().has("person","name","stephen"). ......1> project("colleagues", "employers", "eventsAttended"). ......2> by(fold()) ==>[colleagues:[v[0]],employers:[v[0]],eventsAttended:[v[0]]] Use of project() project() accepts a by() modulator for each specified key which is responsible for the transformation to apply to v[0] for that key. 1 2 3
  • 22. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.V().has("person","name","stephen"). ......1> outE("attends"). ......2> count() ==>2 gremlin> g.V().has("person","name","stephen"). ......1> project("colleagues", "employers", "eventsAttended"). ......2> by(fold()). ......3> by(fold()). ......4> by(outE("attends").count()) ==>[colleagues:[v[0]],employers:[v[0]],eventsAttended:2] Use of project() - “eventsAttended” key Projects v[0] to “eventsAttended” key using the “How many events did Stephen attend?” traversal. “How many events did Stephen attend?” 1 2
  • 23. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.V().has("person","name","stephen"). ......1> out("knows"). ......2> valueMap("name","timeZone") ==>[name:[paras],timeZone:[EST]] gremlin> g.V().has("person","name","stephen"). ......1> out("knows"). ......2> valueMap("name","timeZone"). ......3> by(unfold()) ==>[name:paras,timeZone:EST] Use of project() - “colleagues” key unfold() deconstructs a List to a stream and by() only grabs the first object of the child traversal. The effect is to unwrap the embedded List. “Who does Stephen know?” 1 2
  • 24. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.V().has("person","name","stephen"). ......1> out("knows"). ......2> valueMap("name","timeZone"). ......3> by(unfold()) ==>[name:paras,timeZone:EST] gremlin> g.V().has("person","name","stephen"). ......1> project("colleagues", "employers", "eventsAttended"). ......2> by(out("knows").valueMap("name","timeZone").by(unfold()).fold()). ......3> by(fold()). ......4> by(outE("attends").count()) ==>[colleagues:[[name:paras,timeZone:EST]],employers:[v[0]],eventsAttended:2] Use of project() - “colleagues” key “Who does Stephen know?” Projects v[0] to “colleagues” key using the “Who does Stephen know?” traversal. 1 2
  • 25. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.V().has("person","name","stephen"). ......1> inE("employs"). ......2> order().by("since",desc). ......3> outV(). ......4> valueMap("name","city","state"). ......5> by(unfold()) ==>[city:santa clara,name:datastax,state:CA] gremlin> g.V().has("person","name","stephen"). ......1> project("colleagues","employers","eventsAttended"). ......2> by(out("knows").valueMap("name","timeZone").by(unfold()).fold()). ......3> by(inE("employs"). ......4> order().by("since",desc). ......5> outV(). ......6> valueMap("name","city","state"). ......7> by(unfold()). ......8> fold()). ......9> by(outE("attends").count()).next() ==>colleagues=[{name=paras, timeZone=EST}] ==>employers=[{city=santa clara, name=datastax, state=CA}] ==>eventsAttended=2] Use of project() - “employers” key “Who has employed Stephen?” Projects v[0] to “employers” key using the “Who has employed Stephen?” traversal. 1 2
  • 26. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “How many events did Stephen attend?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). valueMap("name","timeZone"). by(unfold()). fold()). by(inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state"). by(unfold()). fold()). by(outE("attends").count()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 }
  • 27. Gremlin DSLs Building Domain Specific Languages (DSLs) with Gremlin
  • 28. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. A Gremlin- based DSL allows traversals to be written in the language of the application domain.
  • 29. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Benefits of Gremlin DSLs ● Hide traversal complexity ● Improve Gremlin testability ● Improve code readability ● Improve code maintainability and reusability
  • 30. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Gremlin DSL concepts can apply to an application domain, but also to fundamental extension of the graph domain.
  • 31. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } “Who does Stephen know?” “Who has employed Stephen?” “How many events did Stephen attend?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). valueMap("name","timeZone"). by(unfold()). fold()). by(inE("employs"). order().by("since",desc). outV(). valueMap("name","city","state"). by(unfold()). fold()). by(outE("attends").count())
  • 32. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Steps for Collection Construction ● Lists ○ store() ○ aggregate() ○ fold() ○ path() ○ union() ● Maps ○ group()/groupCount() ○ project() ○ select() ○ valueMap()/propertyMap() ○ simpleMap() Collection Manipulation ● unfold() ● range() ● limit() ● tail() This looks like a helpful step!
  • 33. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl ● TinkerPop provides a Java annotation processor in gremlin- core to help build DSLs. ● The @GremlinDsl annotation is applied to an interface that extends the GraphTraversal interface with new steps. ● The annotation processor then generates the appropriate boilerplate code and includes the new step. ● While this topic is discussed in Java, DSLs can be built in any Gremlin Language Variant.
  • 34. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - simpleMap() @GremlinDsl() public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> { default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) { return valueMap(keys).by(__.unfold()); } }
  • 35. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - Usage DseSession session = DseSession.builder().build(); RemoteConnection conn = DseGraph.remoteConnectionBuilder(session).build(); FoundationTraversalSource g = traversal(FoundationTraversalSource.class). withRemote(conn); Map<String,Object> m = g.V().has("person","name","stephen").simpleMap().next();
  • 36. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } “Who does Stephen know?” “Who has employed Stephen?” “How many events did Stephen attend?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(outE("attends").count())
  • 37. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": 2 } “Who does Stephen know?” “Who has employed Stephen?” “How many events did Stephen attend?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(outE("attends").count())
  • 38. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] }
  • 39. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] } out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()
  • 40. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] } out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()
  • 41. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] } out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold() g.V().has("person","name","stephen"). out("attends"). order().by("attendees",desc). simpleMap("name","presentation") g.V().has("person","name","stephen"). out("attends"). order().by("attendees",desc). inE("presents","hosts"). group(). by(label). by(outV().values("name")) 1 1 2 2
  • 42. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] } out("attends"). order().by("attendees",desc). map(union(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). unfold(). group().by(keys).by(select(values))). fold() Merging two Maps!
  • 43. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Steps for Collection Construction ● Lists ○ store() ○ aggregate() ○ fold() ○ path() ○ union() ● Maps ○ group()/groupCount() ○ project() ○ select() ○ valueMap()/propertyMap() ○ singleMap() Collection Manipulation ● unfold() ● range() ● limit() ● tail() ● merge() ● partition() ● interleave() ● zip() These look like helpful steps!
  • 44. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - merge() @GremlinDsl() public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> { default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) { return valueMap(keys).by(__.unfold()); } default GraphTraversal<S, Map> merge(Traversal... maps) { return map(__.union(maps). unfold(). group(). by(keys). by(__.select(values))); } }
  • 45. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). merge(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] } out("attends"). order().by("attendees",desc). merge(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). fold()
  • 46. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. “Who does Stephen know?” “Who has employed Stephen?” “What events has Stephen attended and who were the presenters/hosts?” g.V().has("person","name","stephen"). project("colleagues","employers","eventsAttended"). by(out("knows"). simpleMap("name","timeZone"). fold()). by(inE("employs"). order().by("since",desc). outV(). simpleMap("name","city","state"). fold()). by(out("attends"). order().by("attendees",desc). merge(simpleMap("name","presentation"), inE("presents","hosts"). group(). by(label). by(outV().values("name"))). fold()) { "colleagues": [{ "name": "paras", "timeZone": "EST" }], "employers": [{ "city": "santa clara", "name": "datastax", "state": "CA" }], "eventsAttended": [{ "presentation": "Extending Gremlin...", "hosts": "datastax", "name": "DataStax Accelerate", "presents": "stephen" }, { "presentation": "Gremlin Queries...", "hosts": "paras", "name": "Cassandra & DataStax DC Meetup", "presents": "stephen" }] }
  • 47. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - partition() @GremlinDsl() public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> { default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) { return valueMap(keys).by(__.unfold()); } ... default GraphTraversal<S, List<Object>> partition(int size) { return emit(). until(__.not(__.unfold())). repeat(__.skip(local,size)). filter(__.unfold()). limit(local,size); } }
  • 48. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.inject([1,2,3,4,5,6]) ==>[1,2,3,4,5,6] gremlin> g.inject([1,2,3,4,5,6]).partition(2) ==>[1,2] ==>[3,4] ==>[5,6] gremlin> g.inject([1,2,3,4,5,6]).partition(3) ==>[1,2,3] ==>[4,5,6] Use of partition() 1 2 3
  • 49. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - interleave() @GremlinDsl() public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> { default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) { return valueMap(keys).by(__.unfold()); } ... default GraphTraversal<S,Map<Object,Object>> interleave() { return index(). unfold(). order(). by(__.tail(local)). limit(local,1); }
  • 50. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.inject([1,2,3],['a','b','c'],[7,8,9]).interleave() ==>1 ==>a ==>7 ==>2 ==>b ==>8 ==>3 ==>c ==>9 gremlin> g.inject([1,2,3],['a','b','c'],[7,8,9]).interleave().fold().partition(3) ==>[1,a,7] ==>[2,b,8] ==>[3,c,9] Use of interleave() 1 2
  • 51. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. @GremlinDsl - zip() @GremlinDsl() public interface FoundationTraversalDsl<S,E> extends GraphTraversal.Admin<S,E> { default GraphTraversal<S,Map<Object,Object>> simpleMap(String... keys) { return valueMap(keys).by(__.unfold()); } ... default GraphTraversal<S,Map<Object,Object>> zip() { return ((FoundationTraversal) interleave()). fold(). partition(2). group(). by(__.limit(local,1)). by(__.skip(local,1).unfold()); } } Build more complex DSL steps based on other lower level DSL steps.
  • 52. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.inject(['a','b','c'],[4,5,6]) ==>[a,b,c] ==>[4,5,6] gremlin> g.inject(['a','b','c'],[4,5,6]).zip() ==>[a:4,b:5,c:6] Use of zip() 1 2
  • 53. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. gremlin> g.inject(['a','b','c'],[4,5,6]).zip() ==>[a:4,b:5,c:6] gremlin> g.inject(['a','b','c'],[4,5,6]). ......1> index(). ......2> unfold(). ......3> order(). ......4> by(tail(local)). ......5> limit(local,1).fold(). ......6> emit(). ......7> until(__.not(unfold())). ......8> repeat(skip(local,2)). ......9> filter(unfold()). .....10> limit(local,2). .....11> group(). .....12> by(limit(local,1)). .....13> by(skip(local,1).unfold()) ==>[a:4,b:5,c:6] Use of zip() 1 2
  • 54. © DataStax, All Rights Reserved.ConfidentialConfidential © DataStax, All Rights Reserved. Gremlin DSL Resources 1. DSL Introduction (Java oriented) - https://s.apache.org/bipK 2. DSL design guidelines (Python oriented) - https://s.apache.org/1xiv 3. DSL pattern for “enrichment” (.NET oriented) - https://s.apache.org/knOS 4. DSL sample code - https://s.apache.org/UNiz