Skip to content

Commit

Permalink
Gremlin 2.5.0 releaes.
Browse files Browse the repository at this point in the history
  • Loading branch information
okram committed Apr 14, 2014
1 parent e622d5b commit 9356d7a
Show file tree
Hide file tree
Showing 42 changed files with 3,413 additions and 19 deletions.
6 changes: 3 additions & 3 deletions CHANGELOG.textile
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ h2. Gremlin 2.y.z

!https://github.com/tinkerpop/gremlin/raw/master/doc/images/gremlin-2.png!

h3. Version 2.5.0 (NOT OFFICIALLY RELEASED YET)
h3. Version 2.5.0 (April 14, 2014)

```xml
<dependency>
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-java</artifactId>
<version>2.5.0-SNAPSHOT</version>
<version>2.5.0</version>
</dependency>

<dependency>
<groupId>com.tinkerpop.gremlin</groupId>
<artifactId>gremlin-groovy</artifactId>
<version>2.5.0-SNAPSHOT</version>
<version>2.5.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion README.textile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Gremlin is a domain specific language for traversing property "graphs":http://en
** "TinkerGraph":https://github.com/tinkerpop/blueprints/wiki/TinkerGraph in-memory graph
** "Neo4j":http://neo4j.org/ graph database
** "OrientDB":http://www.orientechnologies.com/ graph database
** "DEX":http://www.sparsity-technologies.com/dex graph database
** "Sparksee":http://www.sparsity-technologies.com/#sparksee graph database
** "Titan":http://thinkaurelius.github.com/titan/ graph database
** "Faunus":http://thinkaurelius.github.com/faunus/ graph analytics engine
** "InfiniteGraph":http://www.objectivity.com/products/infinitegraph/ graph database
Expand Down
15 changes: 15 additions & 0 deletions doc/Acknowledgments.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[[https://github.com/tinkerpop/gremlin/raw/master/doc/images/gremlin-standing-small.png]]

This section provides a list of the people that have contributed in some way to the creation of Gremlin.

# "Marko A. Rodriguez":http://markorodriguez.com -- designed, developed, tested, and documented Gremlin.
# "Pavel Yaskevich":http://github.com/xedin -- designed and developed Gremlin 0.5 compiler and virtual machine.
# "Darrick Wiebe":http://ofallpossibleworlds.wordpress.com/ -- inspired many of Gremlin 0.7+ developments.
# "Peter Neubauer":http://www.linkedin.com/in/neubauer -- aided in the design and the evangelizing of Gremlin.
# "Joshua Shinavier":http://fortytwo.net -- inspired early design choices.
# "Ketrina Yim":http://www.ketrinayim.com/ -- designed the Gremlin logo.
# "Pierre De Wilde":http://www.linkedin.com/in/pierredewilde -- designs and tests new features.

Please review Gremlin's "pom.xml":http://github.com/tinkerpop/gremlin/blob/master/pom.xml. Gremlin would not be possible without the work done by others to create these useful packages.

Join the Gremlin users group at "http://groups.google.com/group/gremlin-users":http://groups.google.com/group/gremlin-users.
68 changes: 68 additions & 0 deletions doc/Backtrack-Pattern.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[[https://github.com/tinkerpop/gremlin/raw/master/doc/images/gremlin-kilt.png]]

Many times its desirable to traverse a particular path and if some criteria is met along that path, then go back to the element from n-steps ago. Examples of such uses cases include:

* "What is the age of my friends who have friends who are older than 30 years old?"
* "What other products have my friends purchased who have also purchased a product of type X?"

```text
g = TinkerGraphFactory.createTinkerGraph()
```

The query below says, in plain English: "What are the ages of the people that know people that are 30+ years old?" The call to @back('x')@ refers to the elements at step @x@ that have paths up to the @back('x')@ step (i.e. back to the @V@ step). In the example below, @back('x')@ "wraps" @out('knows').has('age', T.gt, 30)@.

```text
gremlin> g.V.as('x').outE('knows').inV.has('age', T.gt, 30).back('x').age
==>29
```

A more complicated example is provided over the Grateful Dead graph diagrammed in [[Defining a More Complex Property Graph]].

```text
g = new TinkerGraph()
g.loadGraphML('data/graph-example-2.xml')
```

The example query below states the following:

* get the song with id @89@ (Dark Star).
* get all the songs that follow Dark Star in concert. (*A*)
* get the singers of those songs. (*B*)
* filter to only those songs that are sung by Jerry Garcia. (*C*)
* go back 2 steps to yield those songs that follow Dark Star and are sung by Jerry Garcia. (*D*)
* get the names of those songs that follow Dark Star and are sung by Jerry Garcia.

```text
gremlin> g.v(89).out('followed_by').as('x').out('sung_by').has('name','Garcia').back('x').name
==>EYES OF THE WORLD
==>SING ME BACK HOME
==>MORNING DEW
==>HES GONE
==>CHINA DOLL
==>WHARF RAT
==>BROKEDOWN PALACE
==>TERRAPIN STATION
==>DEAL
==>ATTICS OF MY LIFE
==>COMES A TIME
==>STELLA BLUE
==>BERTHA
```

[[https://github.com/tinkerpop/gremlin/raw/master/doc/images/jerry-followed_by-example.jpg]]

In order to determine how many steps to go back, the @GremlinPipeline.toString()@ can be handy for displaying all the steps in an expression.

```text
gremlin> println g.v(89).out('followed_by').out('sung_by').has('name','Garcia')
[StartPipe, OutPipe(followed_by), OutPipe(sung_by), PropertyFilterPipe(name,EQUAL,Garcia)]
==>null
```

Now, using the @back@ step, notice how @back('x')@ wraps 3 pipes prior to it. The name of the pipe in "Pipes":http://pipes.tinkerpop.com is @BackFilterPipe@.

```text
gremlin> println g.v(89).out('followed_by').as('x').out('sung_by').has('name','Garcia').back('x').name
[StartPipe, AsPipe(x,OutPipe(followed_by)), BackFilterPipe([OutPipe(sung_by), PropertyFilterPipe(name,EQUAL,Garcia)]), PropertyPipe(name)]
==>null
```
101 changes: 101 additions & 0 deletions doc/Basic-Graph-Traversals.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
This section will present basic graph traversals by way of examples on the simple property graph diagrammed below.

!https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-example-1.jpg!

```text
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> v = g.v(1)
==>v[1]
```

The symbol @v@ denotes that the element is a vertex and @1@ denotes the elements unique identifier. To determine all of the outgoing edges from the vertex, the following statement suffices.

```text
gremlin> v.outE
==>e[7][1-knows->2]
==>e[9][1-created->3]
==>e[8][1-knows->4]
```

As a convenience, Gremlin prints the outgoing and incoming vertex identifiers along with the edge label. To acquire the vertices at the head of these edges (known as the incoming vertices), apply another step in the path.

```text
gremlin> v.outE.inV
==>v[2]
==>v[3]
==>v[4]
```

It is important to note that in Gremlin, vertices are incident to edges and edges are incident to vertices. The reason for this will become apparent later when making use of element properties in path expressions. The reserved terms for denoting adjacency selection are the steps @outE@, @inE@, @bothE@, @outV@, @inV@, and @bothV@ (see [[Gremlin Steps]]). The components of a property graph are diagrammed in the example sub-graph below.

!https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-model.jpg!

The process of traversing a graph, in this manner, can continue indefinitely (granted, if there are loops in the graph).

```text
gremlin> v.outE.inV.outE.inV
==>v[5]
==>v[3]
```

There are the steps @out@, @in@, and @both@ that skip over edges as such to jump from vertex to vertex.

```text
gremlin> v.out.out
==>v[5]
==>v[3]
```

Moreover, it is possible to make use of Groovy's language to repeat patterns. For example, the previous example can be denoted as follows.

```text
gremlin> list = [v]
gremlin> for(i in 1..2)
list = list._().out.collect{it}
gremlin> list
==>v[5]
==>v[3]
```

This can also be done using the @loop@ step.

```text
gremlin> v.as('x').out.loop('x'){it.loops < 3}
==>v[5]
==>v[3]
```

If the Gremlin graph data structure was only a directed graph, then outgoing/incoming edges and outgoing/incoming vertices would be the limits of what could be expressed. However, given that vertices and edges can have properties, it is possible to use these properties within a path expression. For example, suppose you want to know the name of vertex 1.

```text
gremlin> v = g.v(1)
==>v[1]
gremlin> v.name
==>marko
```

The @name@ construct denotes the property key @name@ and returns the value of that key. The first component of the path is vertex 1. Thus, the @name@ of vertex 1 is "marko." Another, more complex example that uses vertex and edge properties is to determine the @name@ of the vertices that vertex 1 @knows@ and that are older than 30 years of age, is expressed as such.

```text
gremlin> v.outE('knows').inV.filter{it.age > 30}.name
==>josh
```

In this expression, the @filter{ }@ step serves to filter results of previous step in the path (a closure filter). Thus, @v.outE@ is filtered to only those edges that have a @label@ of "knows." With respect to the diagrammed graph, this leaves only two edges. Next, the incoming vertices at the head of these two edges are determined and then filtered to only those whose @age@ property is greater than 30. Given the diagram, this only leaves vertex 4. In the final segment of the path expression, the @name@ of vertex 4 is selected and what is returned is "josh."

To conclude, let's do a more complicated graph traversal that uses backtracking and an in-line regular expression.

```text
gremlin> v.out('knows').filter{it.age > 21}.as('x').name.filter{it.matches('jo.{2}|JO.{2}')}.back('x').age
==>32
```

With the root vertex being vertex 1, this path expression returns the age of those vertices that vertex 1 knows, are older than 21, and whose names are 4 characters and start with a 'jo' or 'JO'. While contrived, it demonstrates using closures to call functions on properties as well as backtracking to a vertex previously visited.

This expression does the same thing without backtracking. Both are provided in order to demonstrate the many ways in which to express the same thing.

```text
gremlin> v.out('knows').filter{it.age > 21 & it.name.matches('jo.{2}|JO.{2}')}.age
==>32
```
29 changes: 29 additions & 0 deletions doc/Defining-a-More-Complex-Property-Graph.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
The documentation up to this point has been using examples from a simple toy graph of 6 vertices and 6 edges. For this section, a more complicated graph structure is used in the examples. A clipped representation (i.e. low weighted edges removed) of this graph is diagrammed below. This graph is a representation of the American band, the "Grateful Dead":http://en.wikipedia.org/wiki/Grateful_Dead.

!https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-example-2.jpg!

More information about this data set can be found in the following article.

Rodriguez, M.A., Gintautas, V., Pepe, A., "A Grateful Dead Analysis: The Relationship Between Concert and Listening Behavior":http://arxiv.org/abs/0807.2466, First Monday, volume 14, number 1, University of Illinois at Chicago Library, January 2009.

```text
g = new TinkerGraph()
g.loadGraphML('data/graph-example-2.xml')
```

In the above Grateful Dead graph, there are vertices and there are edges. The vertices are broken into two sets: songs (e.g. "Dark Star":http://en.wikipedia.org/wiki/Dark_Star_%28song%29, "China Cat Sunflower":http://en.wikipedia.org/wiki/China_Cat_Sunflower) and artists (e.g. "Jerry Garcia":http://en.wikipedia.org/wiki/Jerry_Garcia, "Robert Hunter":http://en.wikipedia.org/wiki/Robert_Hunter_%28lyricist%29). The following itemization describes the properties associated with vertices and edges.

# vertices
** song vertices
**** type (string): always 'song' for song vertices.
**** name (string): the name of the song.
**** performances (integer): the number of times the song was played in concert.
**** song_type (string): whether the song is a 'cover' song or an 'original'.
** artist vertices
**** type (string): always 'artist' for artist vertices.
**** name (string): the name of the artist.
# edges
** followed_by (song -> song): if the tail song was followed by the head song in concert.
**** weight (integer): the number of times these two songs were paired in concert.
** sung_by (song -> artist): if the tail song was primarily sung by the head artist.
** written_by (song -> artist): if the tail song was written by the head artist.
20 changes: 20 additions & 0 deletions doc/Defining-a-Property-Graph.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Gremlin was designed specifically for the analysis and manipulation of key/value-based, directed, multi-relational graphs. This long term refers to a type of graph data structure that has certain features. These features are described as follows. The first term, key/value, refers to the fact that both vertices and edges can have any number of properties associated with them. The second term, directed, refers to the fact that the edges in the graph have a directionality -- that is, there is a tail and head to each edge. Finally, the third term, multi-relational, refers to the fact that there can many types of edges and thus, many types of relationships can exist between the vertices. For the remainder of this documentation, and for the sake of brevity, these types of graphs will be called *property graphs*. A property graph is demonstrated in the following example. This diagrammed property graph comes with the Gremlin distribution in "GraphML":http://graphml.graphdrawing.org/ format at @data/graph-example-1.xml@ (see "graph-example-1.xml":https://github.com/tinkerpop/gremlin/blob/master/data/graph-example-1.xml) or GraphSON at @data/graph-example-1.json@ (see "graph-example-1.json":https://github.com/tinkerpop/gremlin/blob/master/data/graph-example-1.json)

!https://github.com/tinkerpop/gremlin/raw/master/doc/images/graph-example-1.jpg!

A property graph has these elements:
# a set of vertices
** each vertex has a unique identifier.
** each vertex has a set of outgoing edges.
** each vertex has a set of incoming edges.
** each vertex has a collection of properties defined by a map from key to value.
# a set of edges
** each edge has a unique identifier.
** each edge has an outgoing tail vertex.
** each edge has an incoming head vertex.
** each edge has a label that denotes the type of relationship between its two vertices.
** each edge has a collection of properties defined by a map from key to value.

Learn more about the property graph data model from "Blueprints":http://blueprints.tinkerpop.com.

!https://github.com/tinkerpop/blueprints/raw/master/doc/images/blueprints-logo.png!:http://blueprints.tinkerpop.com
59 changes: 59 additions & 0 deletions doc/Depth-First-vs.-Breadth-First.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
!http://www.cse.unsw.edu.au/~billw/Justsearch1.gif!
[ *Note*: Image linked to from "original webpage":http://www.cse.unsw.edu.au/~billw/Justsearch.html ]

"Depth-first traverse":http://en.wikipedia.org/wiki/Depth-first_search traverses down an entire path as specified by a path expression before turning to the next legal path. On the other hand "breadth-first traverse":http://en.wikipedia.org/wiki/Breadth-first_search traverses legal paths "in parallel," where at each step, all legal objects are computed before moving onto the next step of the path. Gremlin provides support for both types of traversals.

* "Depth-First Traversal":#depth
* "Breadth-First Traversal":#breadth

<a name="depth"></a>

h2(#depth). Depth-First Traversal

Gremlin is naturally a depth-first traversal language/engine. Typical path expression (as used in this documentation) evaluate in a depth-first manner. The following "co-created" expression is a depth-first expression.

```text
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.v(1).outE('created').inV.inE('created').outV
==>v[1]
==>v[4]
==>v[6]
```

In the expression above, the following occurs in the Gremlin evaluator (see [[Defining a Property Graph]] for diagram of graph).

# Vertex @1@ is passed to step @outE@ which yields three outgoing edges.
# The first of these outgoing edges is then passed into the label filter and goes through since its a @created@ edge.
# The edge then goes to the next step @inV@ which produces vertex @3@.
# Vertex @3@ is then passed to @inE@ which yields three edges.
# The first edge is passed to the label filter and passes through because its a @created@ edge.
# The edge is passed to @outV@ which yields vertex @1@.

At this point, the path expression is complete for the full *depth* of the expression (thus, depth-first). The evaluator then goes onto the remaining two edges created from the first @outE@ and the process continues until all legal branches of the path expression have been evaluated.

<a name="breadth"></a>

h2(#breadth). Breadth-First Traversal

!http://upload.wikimedia.org/wikipedia/commons/4/46/Animated_BFS.gif!
[ *Note*: Image linked to from "original webpage":http://en.wikipedia.org/wiki/Breadth-first_search ]

In a breadth-first traversal, all results for each step of the process are gathered before the next step is evaluated. The equivalent breadth-first traversal for the previous "co-created" expression is as follows.

```text
gremlin> g.v(1).outE('created').gather.scatter.inV.gather.scatter.inE('created').gather.scatter.outV.gather.scatter
==>v[1]
==>v[4]
==>v[6]
```

The @gather@ step is used to aggregate all the results of the previous step into a list. Given that @gather@ exhausts all the objects of the previous step and emits a list. The @scatter@ step is used to unroll that list and pass it to the next step.

With @gather@, the generated list can be analyzed by a step to determine some desired property that is a function of all current objects in the breadth of the path. For example.

bc. gremlin> g.v(1).outE.gather{ println "processing: ${it}"; return it.get(0) }.inV
processing: [e[7][1-knows->2], e[8][1-knows->4], e[9][1-created->3]]
==>v[2]

Note that with breadth-first traverse being controlled by the @gather@ step, its possible to intermix the use of depth- and breadth-first traversing in a single path expression. In other words, its not necessary to gather all results from the previous step at every step. In fact, its only necessary when all objects of a particular part of the path expression are needed in a computation.
29 changes: 29 additions & 0 deletions doc/Downloads.textile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
!https://github.com/tinkerpop/gremlin/raw/master/doc/images/gremlin-logo.png!
[[Release Notes]] for all versions
==<hr/>==
* *Gremlin 2.x*
** "Gremlin 2.4.0":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-2.4.0.zip
** "Gremlin 2.3.0":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-2.3.0.zip
** "Gremlin 2.2.0":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-2.2.0.zip
** "Gremlin 2.1.0":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-2.1.0.zip
** "Gremlin 2.0.0":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-2.0.0.zip

* *Gremlin 1.x*
** "Gremlin 1.5":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-1.5.zip
** "Gremlin 1.4":http://tinkerpop.com/downloads/gremlin/gremlin-groovy-1.4.zip
** "Gremlin 1.3":http://tinkerpop.com/downloads/gremlin/gremlin-1.3.zip
** "Gremlin 1.2":http://tinkerpop.com/downloads/gremlin/gremlin-1.2.zip
** "Gremlin 1.1":http://tinkerpop.com/downloads/gremlin/gremlin-1.1.zip
** "Gremlin 1.0":http://tinkerpop.com/downloads/gremlin/gremlin-1.0.zip

* *Gremlin 0.x*
** "Gremlin 0.9":http://tinkerpop.com/downloads/gremlin/gremlin-0.9.zip
** "Gremlin 0.8":http://tinkerpop.com/downloads/gremlin/gremlin-0.8.zip
** "Gremlin 0.7":http://tinkerpop.com/downloads/gremlin/gremlin-0.7.zip
** "Gremlin 0.6":http://tinkerpop.com/downloads/gremlin/gremlin-0.6.zip
** "Gremlin 0.5.5":http://tinkerpop.com/downloads/gremlin/gremlin-0.5.5.zip
** "Gremlin 0.5":http://tinkerpop.com/downloads/gremlin/gremlin-0.5.zip
** "Gremlin 0.2.2":http://tinkerpop.com/downloads/gremlin/gremlin-0.2.2.zip
** "Gremlin 0.2.1":http://tinkerpop.com/downloads/gremlin/gremlin-0.2.1.zip
** "Gremlin 0.2":http://tinkerpop.com/downloads/gremlin/gremlin-0.2.zip
** "Gremlin 0.1":http://tinkerpop.com/downloads/gremlin/gremlin-0.1.zip
Loading

0 comments on commit 9356d7a

Please sign in to comment.