http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/reference/intro.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/intro.asciidoc b/docs/src/reference/intro.asciidoc index 7a7f62f..0f226ec 100644 --- a/docs/src/reference/intro.asciidoc +++ b/docs/src/reference/intro.asciidoc @@ -15,8 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. //// [[intro]] -Introduction to Graph Computing -=============================== += Introduction to Graph Computing image::graph-computing.png[width=350] @@ -84,8 +83,7 @@ then a concise name is provided (e.g. `out()`, `path()`, `repeat()`). If the met providers, then the standard Java naming convention is followed (e.g. `getNextStep()`, `getSteps()`, `getElementComputeKeys()`). -The Graph Structure -------------------- +== The Graph Structure image:gremlin-standing.png[width=125,float=left] A graph's structure is the topology formed by the explicit references between its vertices, edges, and properties. A vertex has incident edges. A vertex is adjacent to another vertex if @@ -124,8 +122,7 @@ WARNING: Many graph systems do not allow the user to specify an element ID and i NOTE: In TinkerPop3, vertices are allowed a single immutable string label (similar to an edge label). This functionality did not exist in TinkerPop2. Element ids are still immutable in TinkerPop3 as they were in TinkerPop2. -Mutating the Graph -~~~~~~~~~~~~~~~~~~ +=== Mutating the Graph Below is a sequence of basic graph mutation operations represented in Java 8. One of the major differences between TinkerPop2 and TinkerPop3 is that in TinkerPop3, the Java convention of using setters and getters has been abandoned @@ -223,8 +220,7 @@ IMPORTANT: TinkerGraph is not a transactional graph. For more information on tra systems that support them) see the section dedicated to <<transactions,transactions>>. [[the-graph-process]] -The Graph Process ------------------ +== The Graph Process image:gremlin-running.png[width=125,float=left] The primary way in which graphs are processed are via graph traversals. The TinkerPop3 process API is focused on allowing users to create graph traversals in a @@ -303,8 +299,7 @@ g.V(marko).out('knows').values('name') <3> <2> Get the vertices that are outgoing adjacent to the marko-vertex via knows-edges. <3> Get the names of the marko-vertex's friends. -The Traverser -~~~~~~~~~~~~~ +=== The Traverser When a traversal is executed, the source of the traversal is on the left of the expression (e.g. vertex 1), the steps are the middle of the traversal (e.g. `out('knows')` and `values('name')`), and the results are "traversal.next()'d" @@ -339,8 +334,7 @@ WARNING: A Traversal's result are never ordered unless explicitly by means of << never rely on the iteration order between TinkerPop3 releases and even within a release (as traversal optimizations may alter the flow). -On Gremlin Language Variants ----------------------------- +== On Gremlin Language Variants Gremlin is written in Java 8. There are various language variants of Gremlin such as Gremlin-Groovy (packaged with TinkerPop3), Gremlin-Python (packaged with TinkerPop3), link:https://github.com/mpollmeier/gremlin-scala[Gremlin-Scala], @@ -383,8 +377,7 @@ typecasting is required. Please see the <<gremlin-variants, Gremlin Variants>> section for more information on this topic. -Graph System Integration ------------------------- +== Graph System Integration image:provider-integration.png[width=395,float=right] TinkerPop is a framework composed of various interoperable components. At the foundation there is the <<graph,core TinkerPop3 API>> which defines what a `Graph`, `Vertex`,
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/reference/preface.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/preface.asciidoc b/docs/src/reference/preface.asciidoc index 516aa4c..f54e168 100644 --- a/docs/src/reference/preface.asciidoc +++ b/docs/src/reference/preface.asciidoc @@ -15,13 +15,11 @@ See the License for the specific language governing permissions and limitations under the License. //// [[preface]] -TinkerPop3 Documentation -======================== += TinkerPop3 Documentation In the beginning... -TinkerPop0 ----------- +== TinkerPop0 Gremlin realized. The more he did so, the more ideas he created. The more ideas he created, the more they related. Into a concatenation of that which he accepted wholeheartedly and that which perhaps may ultimately come to be through @@ -32,8 +30,7 @@ realization. Perhaps, the world is simply an idea that he once had -- The Tinker image::gremlin-logo.png[width=300] -TinkerPop1 ----------- +== TinkerPop1 What is The TinkerPop? Where is The TinkerPop? Who is The TinkerPop? When is The TinkerPop?. The more he wondered, the more these thoughts blurred into a seeming identity -- distinctions unclear. Unwilling to accept the morass of the @@ -63,8 +60,7 @@ Would the machines, by their very nature of realizing The TinkerPop, be The Tink coin, do the machines simply provide the scaffolding by which Gremlin's world sustains itself and yielding its justification by means of the word "The TinkerPop?" Regardless, it all turns out the same -- The TinkerPop. -TinkerPop2 ----------- +== TinkerPop2 Gremlin spoke: @@ -78,8 +74,7 @@ The machines, simply moving algorithmically through Gremlin's world, endorsed hi more efficient, more expressive, better capable of reasoning upon his thoughts. Faster, quickly, now towards the world's end, where there would be forever currently, emanatingly engulfing that which is -- The TinkerPop. -TinkerPop3 ----------- +== TinkerPop3 image::tinkerpop3-splash.png[width=450] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/reference/the-graph.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/the-graph.asciidoc b/docs/src/reference/the-graph.asciidoc index 78856f2..339b392 100644 --- a/docs/src/reference/the-graph.asciidoc +++ b/docs/src/reference/the-graph.asciidoc @@ -15,13 +15,11 @@ See the License for the specific language governing permissions and limitations under the License. //// [[graph]] -The Graph -========= += The Graph image::gremlin-standing.png[width=125] -Features --------- +== Features A `Feature` implementation describes the capabilities of a `Graph` instance. This interface is implemented by graph system providers for two purposes: @@ -53,8 +51,7 @@ WARNING: Assignments of a `GraphStrategy` can alter the base features of a `Grap against a `Feature` may not always reflect the behavior exhibited when the `GraphStrategy` is in use. [[vertex-properties]] -Vertex Properties ------------------ +== Vertex Properties image:vertex-properties.png[width=215,float=left] TinkerPop3 introduces the concept of a `VertexProperty<V>`. All the properties of a `Vertex` are a `VertexProperty`. A `VertexProperty` implements `Property` and as such, it has a @@ -141,8 +138,7 @@ g.V().has('name','gremlin').inE('uses'). select('a','b').by('skill').by('name') // rank the users of gremlin by their skill level ---- -Graph Variables ---------------- +== Graph Variables TinkerPop3 introduces the concept of `Graph.Variables`. Variables are key/value pairs associated with the graph itself -- in essence, a `Map<String,Object>`. These variables are intended to store metadata about the graph. Example @@ -171,8 +167,7 @@ IMPORTANT: Graph variables are not intended to be subject to heavy, concurrent m computations. The intention is to have a location to store data about the graph for administrative purposes. [[transactions]] -Graph Transactions ------------------- +== Graph Transactions image:gremlin-coins.png[width=100,float=right] A link:http://en.wikipedia.org/wiki/Database_transaction[database transaction] represents a unit of work to execute against the database. Transactions are controlled by an implementation of the @@ -203,8 +198,7 @@ graph system provider to choose the specific aspects of how their implementation TinkerPop stack. Be sure to understand the transaction semantics of the specific graph implementation that is being utilized as it may present differing functionality than described here. -Configuring -~~~~~~~~~~~ +=== Configuring Determining when a transaction starts is dependent upon the behavior assigned to the `Transaction`. It is up to the `Graph` implementation to determine the default behavior and unless the implementation doesn't allow it, the behavior @@ -285,8 +279,7 @@ NOTE: It may be important to consult the documentation of the `Graph` implementa specifics of how transactions will behave. TinkerPop allows some latitude in this area and implementations may not have the exact same behaviors and link:https://en.wikipedia.org/wiki/ACID[ACID] guarantees. -Threaded Transactions -~~~~~~~~~~~~~~~~~~~~~ +=== Threaded Transactions Most `Graph` implementations that support transactions do so in a `ThreadLocal` manner, where the current transaction is bound to the current thread of execution. Consider the following example to demonstrate: @@ -349,8 +342,7 @@ In the above case, the call to `graph.tx().createThreadedTx()` creates a new `Gr `ThreadLocal` transaction, thus allowing each thread to operate on it in the same context. In this case, there would be three separate vertices persisted to the `Graph`. -Gremlin I/O ------------ +== Gremlin I/O image:gremlin-io.png[width=250,float=right] The task of getting data in and out of `Graph` instances is the job of the Gremlin I/O packages. Gremlin I/O provides two interfaces for reading and writing `Graph` instances: `GraphReader` @@ -380,8 +372,7 @@ input to `readProperty`. NOTE: Additional documentation for TinkerPop IO formats can be found in the link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/[IO Reference]. -GraphML Reader/Writer -~~~~~~~~~~~~~~~~~~~~~ +=== GraphML Reader/Writer image:gremlin-graphml.png[width=350,float=left] The link:http://graphml.graphdrawing.org/[GraphML] file format is a common XML-based representation of a graph. It is widely supported by graph-related tools and libraries making it a @@ -458,8 +449,7 @@ transformer.transform(source, result); ---- [[graphson-reader-writer]] -GraphSON Reader/Writer -~~~~~~~~~~~~~~~~~~~~~~ +=== GraphSON Reader/Writer image:gremlin-graphson.png[width=350,float=left] GraphSON is a link:http://json.org/[JSON]-based format extended from earlier versions of TinkerPop. It is important to note that TinkerPop3's GraphSON is not backwards compatible @@ -569,14 +559,12 @@ interpret the numeric values. In coercing those Java values to JSON, such infor NOTE: Additional documentation for GraphSON can be found in the link:http://tinkerpop.apache.org/docs/x.y.z/dev/io/#graphson[IO Reference]. [[graphson-types-embedding]] -Types embedding -^^^^^^^^^^^^^^^ +==== Types embedding With a minor change to the construction of the `GraphSONWriter` the lossy nature of GraphSON can be avoided. [[graphson-1-0-types]] -Types with GraphSON 1.0 -+++++++++++++++++++++++ +===== Types with GraphSON 1.0 GraphSON 1.0 is the version enabled by default when creating a GraphSON Mapper. Here is how to enable types with GraphSON 1.0: @@ -679,8 +667,7 @@ non-JVM languages won't be able to consume this information automatically, at le values should be coerced back into the correct types in the target language. [[graphson-2-0-types]] -GraphSON 2.0 -++++++++++++ +===== GraphSON 2.0 GraphSON 2.0 has been introduced to improve the format of the typed values from GraphSON 1.0. It provides non-Java centric types information in a consistent format. @@ -802,8 +789,7 @@ By disabling types, the JSON payload produced will lack the extra information th disabling types can be unsafe with regards to the written data in that types can be lost. [[gryo-reader-writer]] -Gryo Reader/Writer -~~~~~~~~~~~~~~~~~~ +=== Gryo Reader/Writer image:gremlin-kryo.png[width=400,float=left] link:https://github.com/EsotericSoftware/kryo[Kryo] is a popular serialization package for the JVM. Gremlin-Kryo is a binary `Graph` serialization format for use on the JVM by JVM @@ -848,8 +834,7 @@ try (final InputStream stream = new FileInputStream("tinkerpop-modern.kryo")) { NOTE: The preferred extension for files names produced by Gryo is `.kryo`. -TinkerPop2 Data Migration -~~~~~~~~~~~~~~~~~~~~~~~~~ +=== TinkerPop2 Data Migration image:data-migration.png[width=300,float=right] For those using TinkerPop2, migrating to TinkerPop3 will mean a number of programming changes, but may also require a migration of the data depending on the graph implementation. For @@ -900,8 +885,7 @@ gremlin> g.E() ==>e[10][4-created->5] ---- -Namespace Conventions ---------------------- +== Namespace Conventions End users, <<implementations,graph system providers>>, <<graphcomputer,`GraphComputer`>> algorithm designers, <<gremlin-plugins,GremlinPlugin>> creators, etc. all leverage properties on elements to store information. There are http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/reference/the-graphcomputer.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/the-graphcomputer.asciidoc b/docs/src/reference/the-graphcomputer.asciidoc index b03c891..0fb9daa 100644 --- a/docs/src/reference/the-graphcomputer.asciidoc +++ b/docs/src/reference/the-graphcomputer.asciidoc @@ -15,8 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. //// [[graphcomputer]] -The GraphComputer -================= += The GraphComputer image:graphcomputer-puffers.png[width=350,float=right] TinkerPop3 provides two primary means of interacting with a graph: link:http://en.wikipedia.org/wiki/Online_transaction_processing[online transaction processing] (OLTP) and @@ -51,8 +50,7 @@ rely heavily on the state of the computing classes (not the structure, but the p `Configuration`. [[vertexprogram]] -VertexProgram -------------- +== VertexProgram image:bsp-diagram.png[width=400,float=right] GraphComputer takes a `VertexProgram`. A VertexProgram can be thought of as a piece of code that is executed at each vertex in logically parallel manner until some termination condition is @@ -93,8 +91,7 @@ link:https://hama.apache.org/[Hama]. TinkerPop3 extends the popularized model with integrated post-processing <<mapreduce,MapReduce>> jobs over the vertex set. [[mapreduce]] -MapReduce ---------- +== MapReduce The BSP model proposed by Pregel stores the results of the computation in a distributed manner as properties on the elements in the graph. In many situations, it is necessary to aggregate those resultant properties into a single @@ -163,8 +160,7 @@ MapReduce jobs are executed is irrelevant. This is made apparent when realizing `Vertex` as its input and the `reduce()`-stage yields key/value pairs. Thus, the results of reduce can not fed back into a `map()`. -A Collection of VertexPrograms ------------------------------- +== A Collection of VertexPrograms TinkerPop3 provides a collection of VertexPrograms that implement common algorithms. This section discusses the various implementations. @@ -172,8 +168,7 @@ IMPORTANT: The vertex programs presented are what are provided as of TinkerPop x more algorithms will be added. [[pagerankvertexprogram]] -PageRankVertexProgram -~~~~~~~~~~~~~~~~~~~~~ +=== PageRankVertexProgram image:gremlin-pagerank.png[width=400,float=right] link:http://en.wikipedia.org/wiki/PageRank[PageRank] is perhaps the most popular OLAP-oriented graph algorithm. This link:http://en.wikipedia.org/wiki/Centrality[eigenvector centrality] @@ -350,8 +345,7 @@ g.V().pageRank().by('pageRank').times(5).order().by('pageRank').valueMap() ---- [[peerpressurevertexprogram]] -PeerPressureVertexProgram -~~~~~~~~~~~~~~~~~~~~~~~~~ +=== PeerPressureVertexProgram The `PeerPressureVertexProgram` is a clustering algorithm that assigns a nominal value to each vertex in the graph. The nominal value represents the vertex's cluster. If two vertices have the same nominal value, then they are in the @@ -374,8 +368,7 @@ g.V().peerPressure().by(outE('knows')).by('cluster').valueMap() ---- [[bulkdumpervertexprogram]] -BulkDumperVertexProgram -~~~~~~~~~~~~~~~~~~~~~~~ +=== BulkDumperVertexProgram The `BulkDumperVertexProgram` can be used to export a whole graph in any of the provided Hadoop GraphOutputFormats (e.g. `GraphSONOutputFormat`, `GryoOutputFormat` or `ScriptOutputFormat`). The input can be any Hadoop GraphInputFormat @@ -383,8 +376,7 @@ The `BulkDumperVertexProgram` can be used to export a whole graph in any of the is provided in the SparkGraphComputer section. [[bulkloadervertexprogram]] -BulkLoaderVertexProgram -~~~~~~~~~~~~~~~~~~~~~~~ +=== BulkLoaderVertexProgram image:batch-graph.png[width=220,float=left] The `BulkLoaderVertexProgram` provides a generalized way for loading graphs of any size into a persistent `Graph`. It is especially useful for large graphs (i.e. hundreds of millions @@ -443,8 +435,7 @@ graph is a `HadoopGraph`. `BulkLoaderVertexProgram` will likely fail with a `Fas edges is missing. [[traversalvertexprogram]] -TraversalVertexProgram -~~~~~~~~~~~~~~~~~~~~~~ +=== TraversalVertexProgram image:traversal-vertex-program.png[width=250,float=left] The `TraversalVertexProgram` is a "special" VertexProgram in that it can be executed via a `Traversal` and a `GraphComputer`. In Gremlin, it is possible to have @@ -496,8 +487,7 @@ result.memory().runtime ---- [[distributed-gremlin-gotchas]] -Distributed Gremlin Gotchas -^^^^^^^^^^^^^^^^^^^^^^^^^^^ +==== Distributed Gremlin Gotchas Gremlin OLTP is not identical to Gremlin OLAP. @@ -534,8 +524,7 @@ to maintain the ordering of `g.V().hasLabel("person").order().by("age").values(" will rebroadcast traversers across the cluster. [[graph-filter]] -Graph Filter ------------- +== Graph Filter Most OLAP jobs do not require the entire source graph to faithfully execute their `VertexProgram`. For instance, if `PageRankVertexProgram` is only going to compute the centrality of people in the friendship-graph, then the following http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/reference/the-traversal.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc index d4c9efa..167073a 100644 --- a/docs/src/reference/the-traversal.asciidoc +++ b/docs/src/reference/the-traversal.asciidoc @@ -15,8 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. //// [[traversal]] -The Traversal -============= += The Traversal image::gremlin-running.png[width=125] @@ -38,8 +37,7 @@ and decoration strategies can reason on the underlying traversal sequence. If ne traversal strategies may not function properly. [[graph-traversal-steps]] -Graph Traversal Steps ---------------------- +== Graph Traversal Steps image::step-types.png[width=650] @@ -59,8 +57,7 @@ when using anonymous traversals. For example, `in` and `as` are reserved keyword the verbose syntax `__.in()` and `__.as()` to avoid collisions. [[general-steps]] -General Steps -~~~~~~~~~~~~~ +=== General Steps There are five general steps, each having a traversal and a lambda representation, by which all other specific steps described later extend. @@ -145,8 +142,7 @@ g.V().choose(has('name','marko'), <3> The more specific boolean-based `choose()`-step is implemented as a `branch()`. [[terminal-steps]] -Terminal Steps -~~~~~~~~~~~~~~ +=== Terminal Steps Typically, when a step is concatenated to a traversal a traversal is returned. In this way, a traversal is built up in a link:https://en.wikipedia.org/wiki/Fluent_interface[fluent], link:https://en.wikipedia.org/wiki/Monoid[monadic] fashion. @@ -178,8 +174,7 @@ g.V().out('created').fill(results) <8> Finally, <<explain-step,`explain()`>>-step is also a terminal step and is described in its own section. [[addedge-step]] -AddEdge Step -~~~~~~~~~~~~ +=== AddEdge Step link:http://en.wikipedia.org/wiki/Automated_reasoning[Reasoning] is the process of making explicit what is implicit in the data. What is explicit in a graph are the objects of the graph -- i.e. vertices and edges. What is implicit @@ -218,8 +213,7 @@ g.E(23).valueMap() supports user provided ids. [[addvertex-step]] -AddVertex Step -~~~~~~~~~~~~~~ +=== AddVertex Step The `addV()`-step is used to add vertices to the graph (*map*/*sideEffect*). For every incoming object, a vertex is created. Moreover, `GraphTraversalSource` maintains an `addV()` method. @@ -234,8 +228,7 @@ g.V().has('name','nothing').bothE() ---- [[addproperty-step]] -AddProperty Step -~~~~~~~~~~~~~~~~ +=== AddProperty Step The `property()`-step is used to add properties to the elements of the graph (*sideEffect*). Unlike `addV()` and `addE()`, `property()` is a full sideEffect step in that it does not return the property it created, but the element @@ -258,8 +251,7 @@ g.V(1).properties('friendWeight').valueMap() <3> [[aggregate-step]] -Aggregate Step -~~~~~~~~~~~~~~ +=== Aggregate Step image::aggregate-step.png[width=800] @@ -298,8 +290,7 @@ g.V().out('knows').aggregate('x').by('name').cap('x') ---- [[and-step]] -And Step -~~~~~~~~ +=== And Step The `and()`-step ensures that all provided traversals yield a result (*filter*). Please see <<or-step,`or()`>> for or-semantics. @@ -323,8 +314,7 @@ g.V().where(outE('created').and().outE('knows')).values('name') ---- [[as-step]] -As Step -~~~~~~~ +=== As Step The `as()`-step is not a real step, but a "step modulator" similar to <<by-step,`by()`>> and <<option-step,`option()`>>. With `as()`, it is possible to provide a label to the step that can later be accessed by steps and data structures @@ -351,8 +341,7 @@ g.V().hasLabel('software').as('a','b','c'). ---- [[barrier-step]] -Barrier Step -~~~~~~~~~~~~ +=== Barrier Step The `barrier()`-step (*barrier*) turns the lazy traversal pipeline into a bulk-synchronous pipeline. This step is useful in the following situations: @@ -406,8 +395,7 @@ g.V().both().both().both().count().iterate().toString() <2> <1> With `LazyBarrierStrategy` activated, `barrier()` steps are automatically inserted where appropriate. [[by-step]] -By Step -~~~~~~~ +=== By Step The `by()`-step is not an actual step, but instead is a "step-modulator" similar to <<as-step,`as()`>> and <<option-step,`option()`>>. If a step is able to accept traversals, functions, comparators, etc. then `by()` is the @@ -444,8 +432,7 @@ on a step-by-step level and thus, as discussed in their respective section of th * <<store-step, `store()`>>: store all objects into a set but only store their `by()`-modulated values. [[cap-step]] -Cap Step -~~~~~~~~ +=== Cap Step The `cap()`-step (*barrier*) iterates the traversal up to itself and emits the sideEffect referenced by the provided key. If multiple keys are provided, then a `Map<String,Object>` of sideEffects is emitted. @@ -460,8 +447,7 @@ g.V().groupCount('a').by(label).groupCount('b').by(outE().count()).cap('a','b') <2> Same as statement 1, but also emit the side effect labeled 'b' which groups vertices by the number of out edges. [[choose-step]] -Choose Step -~~~~~~~~~~~ +=== Choose Step image::choose-step.png[width=700] @@ -517,8 +503,7 @@ g.V().hasLabel('person'). ---- [[coalesce-step]] -Coalesce Step -~~~~~~~~~~~~~ +=== Coalesce Step The `coalesce()`-step evaluates the provided traversals in order and returns the first traversal that emits at least one element. @@ -532,8 +517,7 @@ g.V().hasLabel('person').coalesce(values('nickname'), values('name')) ---- [[coin-step]] -Coin Step -~~~~~~~~~ +=== Coin Step To randomly filter out a traverser, use the `coin()`-step (*filter*). The provided double argument biases the "coin toss." @@ -545,8 +529,7 @@ g.V().coin(1.0) ---- [[constant-step]] -Constant Step -~~~~~~~~~~~~~ +=== Constant Step To specify a constant value for a traverser, use the `constant()`-step (*map*). This is often useful with conditional steps like <<choose-step,`choose()`-step>> or <<coalesce-step,`coalesce()`-step>>. @@ -565,8 +548,7 @@ g.V().coalesce( <2> Same as statement 1 (unless there is a person vertex with no name). [[count-step]] -Count Step -~~~~~~~~~~ +=== Count Step image::count-step.png[width=195] @@ -587,8 +569,7 @@ IMPORTANT: `count(local)` counts the current, local object (not the objects in t `Collection`- and `Map`-type objects. For any other object, a count of 1 is returned. [[cyclicpath-step]] -CyclicPath Step -~~~~~~~~~~~~~~~ +=== CyclicPath Step image::cyclicpath-step.png[width=400] @@ -613,8 +594,7 @@ g.V(1).as('a').out('created').as('b'). ---- [[dedup-step]] -Dedup Step -~~~~~~~~~~ +=== Dedup Step With `dedup()`-step (*filter*), repeatedly seen objects are removed from the traversal stream. Note that if a traverser's bulk is greater than 1, then it is set to 1 before being emitted. @@ -649,8 +629,7 @@ g.V().as('a').out('created').as('b').in('created').as('c').dedup('a','b').select <1> If the current `a` and `b` combination has been seen previously, then filter the traverser. [[drop-step]] -Drop Step -~~~~~~~~~ +=== Drop Step The `drop()`-step (*filter*/*sideEffect*) is used to remove element and properties from the graph (i.e. remove). It is a filter step because the traversal yields no outgoing objects. @@ -666,8 +645,7 @@ g.V() ---- [[explain-step]] -Explain Step -~~~~~~~~~~~~ +=== Explain Step The `explain()`-step (*terminal*) will return a `TraversalExplanation`. A traversal explanation details how the traversal (prior to `explain()`) will be compiled given the registered <<traversalstrategy,traversal strategies>>. @@ -684,8 +662,7 @@ g.V().hasLabel('person').outE().identity().inV().count().is(gt(5)).explain() For traversal profiling information, please see <<profile-step,`profile()`>>-step. [[fold-step]] -Fold Step -~~~~~~~~~ +=== Fold Step There are situations when the traversal stream needs a "barrier" to aggregate all the objects and emit a computation that is a function of the aggregate. The `fold()`-step (*map*) is one particular instance of this. Please see @@ -710,8 +687,7 @@ g.V().values('age').sum() <6> <6> The same as before, but using the <<sum-step,`sum()`-step>>. [[graph-step]] -Graph Step -~~~~~~~~~~ +=== Graph Step The `V()`-step is usually used to start a `GraphTraversal`, but can also be used mid-traversal. @@ -735,8 +711,7 @@ g.V().has('name', within('marko', 'vadas', 'josh')).as('person'). <2> Whether the graph system provider supports mid-traversal `V()` index lookups or not can easily be determined by inspecting the `toString()` output of the iterated traversal. If `has` conditions were folded into the `V()`-step, an index - if one exists - will be used. [[from-step]] -From Step -~~~~~~~~~ +=== From Step The `from()`-step is not an actual step, but instead is a "step-modulator" similar to <<as-step,`as()`>> and <<by-step,`by()`>>. If a step is able to accept traversals or strings then `from()` is the @@ -746,8 +721,7 @@ The list of steps that support `from()`-modulation are: <<simplepath-step,`simpl <<path-step,`path()`>>, and <<addedge-step,`addE()`>>. [[group-step]] -Group Step -~~~~~~~~~~ +=== Group Step As traversers propagate across a graph as defined by a traversal, sideEffect computations are sometimes required. That is, the actual path taken or the current location of a traverser is not the ultimate output of the computation, @@ -772,8 +746,7 @@ The two projection parameters available to `group()` via `by()` are: . Value-projection: What feature of the group to store in the key-list? [[groupcount-step]] -GroupCount Step -~~~~~~~~~~~~~~~ +=== GroupCount Step When it is important to know how many times a particular object has been at a particular part of a traversal, `groupCount()`-step (*map*/*sideEffect*) is used. @@ -805,8 +778,7 @@ The above is interesting in that it demonstrates the use of referencing the inte it received to its output. Internal to `groupCount()`, the object's count is incremented. [[has-step]] -Has Step -~~~~~~~~ +=== Has Step image::has-step.png[width=670] @@ -852,8 +824,7 @@ TinkerPop does not support a regular expression predicate, although specific gra may provide a partial match extension. [[id-step]] -Id Step -~~~~~~~ +=== Id Step The `id()`-step (*map*) takes an `Element` and extracts its identifier from it. @@ -866,8 +837,7 @@ g.V(1).properties().id() ---- [[inject-step]] -Inject Step -~~~~~~~~~~~ +=== Inject Step image::inject-step.png[width=800] @@ -893,8 +863,7 @@ inject(1,2).map {it.get() + 1}.map {g.V(it.get()).next()}.values('name') ---- [[is-step]] -Is Step -~~~~~~~ +=== Is Step It is possible to filter scalar values using `is()`-step (*filter*). @@ -914,8 +883,7 @@ g.V().where(__.in('created').values('age'). <3> Find projects whose contributors average age is between 30 and 35. [[label-step]] -Label Step -~~~~~~~~~~ +=== Label Step The `label()`-step (*map*) takes an `Element` and extracts its label from it. @@ -927,8 +895,7 @@ g.V(1).properties().label() ---- [[key-step]] -Key Step -~~~~~~~~ +=== Key Step The `key()`-step (*map*) takes a `Property` and extracts the key from it. @@ -939,8 +906,7 @@ g.V(1).properties().properties().key() ---- [[limit-step]] -Limit Step -~~~~~~~~~~ +=== Limit Step The `limit()`-step is analogous to <<range-step,`range()`-step>> save that the lower end range is set to 0. @@ -964,8 +930,7 @@ g.V().valueMap().limit(local, 1) <2> <2> `Map<String, Object>` for each vertex, but containing only the first property value. [[local-step]] -Local Step -~~~~~~~~~~ +=== Local Step image::local-step.png[width=450] @@ -1006,8 +971,7 @@ of computing is the vertex and its local "star graph," it is important that the the confines of the vertex's star graph. In other words, it can not traverse to an adjacent vertex's properties or edges. [[loops-step]] -Loops Step -~~~~~~~~~~ +=== Loops Step The `loops()`-step (*map*) extracts the number of times the `Traverser` has gone through the current loop. @@ -1017,8 +981,7 @@ g.V().emit(__.has("name", "marko").or().loops().is(2)).repeat(__.out()).values(" ---- [[match-step]] -Match Step -~~~~~~~~~~ +=== Match Step The `match()`-step (*map*) provides a more link:http://en.wikipedia.org/wiki/Declarative_programming[declarative] form of graph querying based on the notion of link:http://en.wikipedia.org/wiki/Pattern_matching[pattern matching]. @@ -1196,8 +1159,7 @@ g.V().as('a').out().as('b'). <1> <8> The bound values are of different types -- vertex ("a"), vertex ("b"), long ("c"). [[using-where-with-match]] -Using Where with Match -^^^^^^^^^^^^^^^^^^^^^^ +==== Using Where with Match Match is typically used in conjunction with both `select()` (demonstrated previously) and `where()` (presented here). A `where()`-step allows the user to further constrain the result set provided by `match()`. @@ -1241,8 +1203,7 @@ IMPORTANT: A `where()`-step is a filter and thus, variables within a `where()` c path of the traverser in `match()`. As such, `where()`-steps in `match()` are used for filtering, not binding. [[max-step]] -Max Step -~~~~~~~~ +=== Max Step The `max()`-step (*map*) operates on a stream of numbers and determines which is the largest number in the stream. @@ -1256,8 +1217,7 @@ IMPORTANT: `max(local)` determines the max of the current, local object (not the This works for `Collection` and `Number`-type objects. For any other object, a max of `Double.NaN` is returned. [[mean-step]] -Mean Step -~~~~~~~~~ +=== Mean Step The `mean()`-step (*map*) operates on a stream of numbers and determines the average of those numbers. @@ -1275,8 +1235,7 @@ IMPORTANT: `mean(local)` determines the mean of the current, local object (not t This works for `Collection` and `Number`-type objects. For any other object, a mean of `Double.NaN` is returned. [[min-step]] -Min Step -~~~~~~~~ +=== Min Step The `min()`-step (*map*) operates on a stream of numbers and determines which is the smallest number in the stream. @@ -1290,8 +1249,7 @@ IMPORTANT: `min(local)` determines the min of the current, local object (not the This works for `Collection` and `Number`-type objects. For any other object, a min of `Double.NaN` is returned. [[not-step]] -Not Step -~~~~~~~~ +=== Not Step The `not()`-step (*filter*) removes objects from the traversal stream when the traversal provided as an argument does not return any objects. @@ -1306,14 +1264,12 @@ g.V().hasLabel('person'). <1> josh created two projects and vadas none [[option-step]] -Option Step -~~~~~~~~~~~ +=== Option Step An option to a <<branch-step,`branch()`>> or <<choose-step,`choose()`>>. [[optional-step]] -Optional Step -~~~~~~~~~~~~~ +=== Optional Step The `optional()`-step (*map*) returns the result of the specified traversal if it yields a result else it returns the calling element, i.e. the `identity()`. @@ -1337,8 +1293,7 @@ g.V().hasLabel('person').optional(out("knows").optional(out("created"))).path() <1> Returns the paths of everybody followed by who they know followed by what they created. [[or-step]] -Or Step -~~~~~~~ +=== Or Step The `or()`-step ensures that at least one of the provided traversals yield a result (*filter*). Please see <<and-step,`and()`>> for and-semantics. @@ -1363,8 +1318,7 @@ g.V().where(outE('created').or().outE('knows')).values('name') ---- [[order-step]] -Order Step -~~~~~~~~~~ +=== Order Step When the objects of the traversal stream need to be sorted, `order()`-step (*map*) can be leveraged. @@ -1425,8 +1379,7 @@ g.V().groupCount().by(inE().count()).order(local).by(keys, incr) <4> NOTE: The `values` and `keys` enums are from `Column` which is used to select "columns" from a `Map`, `Map.Entry`, or `Path`. [[pagerank-step]] -PageRank Step -~~~~~~~~~~~~~ +=== PageRank Step The `pageRank()`-step (*map*/*sideEffect*) calculates link:http://en.wikipedia.org/wiki/PageRank[PageRank] using <<pagerankvertexprogram,`PageRankVertexProgram`>>. @@ -1456,8 +1409,7 @@ g.V().hasLabel('person'). ---- [[path-step]] -Path Step -~~~~~~~~~ +=== Path Step A traverser is transformed as it moves through a series of steps within a traversal. The history of the traverser is realized by examining its path with `path()`-step (*map*). @@ -1503,8 +1455,7 @@ In OLAP there are optimizations provided for traverser populations, but when pat is unique due to its history), then these optimizations are no longer possible. [[path-data-structure]] -Path Data Structure -^^^^^^^^^^^^^^^^^^^ +==== Path Data Structure The `Path` data structure is an ordered list of objects, where each object is associated to a `Set<String>` of labels. An example is presented below to demonstrate both the `Path` API as well as how a traversal yields labeled paths. @@ -1527,8 +1478,7 @@ path.d == path.e ---- [[peerpressure-step]] -PeerPressure Step -~~~~~~~~~~~~~~~~~ +=== PeerPressure Step The `peerPressure()`-step (*map*/*sideEffect*) clusters vertices using <<peerpressurevertexprogram,`PeerPressureVertexProgram`>>. @@ -1544,8 +1494,7 @@ g.V().hasLabel('person'). ---- [[profile-step]] -Profile Step -~~~~~~~~~~~~ +=== Profile Step The `profile()`-step (*sideEffect*) exists to allow developers to profile their traversals to determine statistical information like step runtime, counts, etc. @@ -1585,8 +1534,7 @@ metrics = t.getSideEffects().get('metrics') For traversal compilation information, please see <<explain-step,`explain()`>>-step. [[project-step]] -Project Step -~~~~~~~~~~~~ +=== Project Step The `project()`-step (*map*) projects the current object into a `Map<String,Object>` keyed by provided labels. It is similar to <<select-step,`select()`>>-step, save that instead of retrieving and modulating historic traverser state, it modulates @@ -1607,8 +1555,7 @@ g.V().has('name','marko'). ---- [[program-step]] -Program Step -~~~~~~~~~~~~ +=== Program Step The `program()`-step (*map*/*sideEffect*) is the "lambda" step for `GraphComputer` jobs. The step takes a <<vertexprogram,`VertexProgram`>> as an argument and will process the incoming graph accordingly. Thus, the user @@ -1703,8 +1650,7 @@ g.V().hasLabel('person'). ---- [properties-step]] -Properties Step -~~~~~~~~~~~~~~~ +=== Properties Step The `properties()`-step (*map*) extracts properties from an `Element` in the traversal stream. @@ -1716,8 +1662,7 @@ g.V(1).properties('location').has('endTime').valueMap() ---- [[propertymap-step]] -PropertyMap Step -~~~~~~~~~~~~~~~~ +=== PropertyMap Step The `propertiesMap()`-step yields a Map representation of the properties of an element. @@ -1730,8 +1675,7 @@ g.E().propertyMap() ---- [[range-step]] -Range Step -~~~~~~~~~~ +=== Range Step As traversers propagate through the traversal, it is possible to only allow a certain number of them to pass through with `range()`-step (*filter*). When the low-end of the range is not met, objects are continued to be iterated. When @@ -1763,8 +1707,7 @@ g.V().valueMap().select('location').range(local, 1, 3) ---- [[repeat-step]] -Repeat Step -~~~~~~~~~~~ +=== Repeat Step image::gremlin-fade.png[width=350] @@ -1841,8 +1784,7 @@ anonymous traversals do not leave the confines of the vertex's star graph. In ot an adjacent vertex's properties or edges. [[sack-step]] -Sack Step -~~~~~~~~~ +=== Sack Step image:gremlin-sacks-running.png[width=175,float=right] A traverser can contain a local data structure called a "sack". The `sack()`-step is used to read and write sacks (*sideEffect* or *map*). Each sack of each traverser is created @@ -1922,8 +1864,7 @@ g.withBulk(false).withSack(1.0f).V(1).local(outE('knows').barrier(normSack).inV( [[sample-step]] -Sample Step -~~~~~~~~~~~ +=== Sample Step The `sample()`-step is useful for sampling some number of traversers previous in the traversal. @@ -1954,8 +1895,7 @@ g.V(1).repeat(local( ---- [[select-step]] -Select Step -~~~~~~~~~~~ +=== Select Step link:http://en.wikipedia.org/wiki/Functional_programming[Functional languages] make use of function composition and lazy evaluation to create complex computations from primitive operations. This is exactly what `Traversal` does. One @@ -2040,8 +1980,7 @@ g.V(1).as("a").repeat(out().as("a")).times(2).select(all, "a") ---- [[using-where-with-select]] -Using Where with Select -^^^^^^^^^^^^^^^^^^^^^^^ +==== Using Where with Select Like <<match-step,`match()`>>-step, it is possible to use `where()`, as where is a filter that processes `Map<String,Object>` streams. @@ -2066,8 +2005,7 @@ ensure respective `a` and `b` strings are not the same. binding is filtered if `a` doesn't know `b`. The second and final `select()` projects the name of the vertices. [[simplepath-step]] -SimplePath Step -~~~~~~~~~~~~~~~ +=== SimplePath Step image::simplepath-step.png[width=400] @@ -2116,8 +2054,7 @@ g.V('A').as('a'). cross the vertices from the first path. [[store-step]] -Store Step -~~~~~~~~~~ +=== Store Step When link:http://en.wikipedia.org/wiki/Lazy_evaluation[lazy] aggregation is needed, `store()`-step (*sideEffect*) should be used over <<aggregate-step,`aggregate()`>>. The two steps differ in that `store()` does not block and only @@ -2139,8 +2076,7 @@ g.E().store('x').by('weight').cap('x') ---- [[subgraph-step]] -Subgraph Step -~~~~~~~~~~~~~ +=== Subgraph Step image::subgraph-logo.png[width=380] @@ -2185,8 +2121,7 @@ IMPORTANT: The `subgraph()`-step only writes to graphs that support user supplie if no graph is specified via `withSideEffect()`, then <<tinkergraph-gremlin,TinkerGraph>> is assumed. [[sum-step]] -Sum Step -~~~~~~~~ +=== Sum Step The `sum()`-step (*map*) operates on a stream of numbers and sums the numbers together to yield a double. Note that the current traverser number is multiplied by the traverser bulk to determine how many such numbers are being @@ -2202,8 +2137,7 @@ IMPORTANT: `sum(local)` determines the sum of the current, local object (not the This works for `Collection`-type objects. For any other object, a sum of `Double.NaN` is returned. [[tail-step]] -Tail Step -~~~~~~~~~ +=== Tail Step image::tail-step.png[width=530] @@ -2238,8 +2172,7 @@ g.V().valueMap().tail(local) <4> <4> `Map<String, Object>` for each vertex, but containing only the last property value. [[timelimit-step]] -TimeLimit Step -~~~~~~~~~~~~~~ +=== TimeLimit Step In many situations, a graph traversal is not about getting an exact answer as its about getting a relative ranking. A classic example is link:http://en.wikipedia.org/wiki/Recommender_system[recommendation]. What is desired is a @@ -2266,8 +2199,7 @@ reached, any `next()` evaluation of the step will yield a `NoSuchElementExceptio yield `false`. [[to-step]] -To Step -~~~~~~~ +=== To Step The `to()`-step is not an actual step, but instead is a "step-modulator" similar to <<as-step,`as()`>> and <<by-step,`by()`>>. If a step is able to accept traversals or strings then `to()` is the @@ -2277,8 +2209,7 @@ The list of steps that support `to()`-modulation are: <<simplepath-step,`simpleP <<path-step,`path()`>>, and <<addedge-step,`addE()`>>. [[tree-step]] -Tree Step -~~~~~~~~~ +=== Tree Step From any one element (i.e. vertex or edge), the emanating paths from that element can be aggregated to form a link:http://en.wikipedia.org/wiki/Tree_(data_structure)[tree]. Gremlin provides `tree()`-step (*sideEffect*) for such @@ -2320,8 +2251,7 @@ g.V().has('name','josh').out('created').values('name'). [[unfold-step]] -Unfold Step -~~~~~~~~~~~ +=== Unfold Step If the object reaching `unfold()` (*flatMap*) is an iterator, iterable, or map, then it is unrolled into a linear form. If not, then the object is simply emitted. Please see <<fold-step,`fold()`>> step for the inverse behavior. @@ -2342,8 +2272,7 @@ inject(1,[2,3,[4,5,[6]]]).repeat(unfold()).until(count(local).is(1)).unfold() ---- [[union-step]] -Union Step -~~~~~~~~~~ +=== Union Step image::union-step.png[width=650] @@ -2362,8 +2291,7 @@ g.V(4).union( ---- [[value-step]] -Value Step -~~~~~~~~~~ +=== Value Step The `value()`-step (*map*) takes a `Property` and extracts the value from it. @@ -2374,8 +2302,7 @@ g.V(1).properties().properties().value() ---- [[valuemap-step]] -ValueMap Step -~~~~~~~~~~~~~ +=== ValueMap Step The `valueMap()`-step yields a Map representation of the properties of an element. @@ -2410,8 +2337,7 @@ g.V().hasLabel('person').properties('location').valueMap(true) ---- [values-step]] -Values Step -~~~~~~~~~~~ +=== Values Step The `values()`-step (*map*) extracts the values of properties from an `Element` in the traversal stream. @@ -2423,8 +2349,7 @@ g.V(1).properties('location').values() ---- [[vertex-steps]] -Vertex Steps -~~~~~~~~~~~~ +=== Vertex Steps image::vertex-steps.png[width=350] @@ -2464,8 +2389,7 @@ g.V(4).inE().bothV() <5> Moving forward only touching vertices. [[where-step]] -Where Step -~~~~~~~~~~ +=== Where Step The `where()`-step filters the current object based on either the object itself (`Scope.local`) or the path history of the object (`Scope.global`) (*filter*). This step is typically used in conjuction with either @@ -2525,8 +2449,7 @@ edges. Note that is only a temporary limitation that will be addressed in a futu link:https://issues.apache.org/jira/browse/TINKERPOP-693[TINKERPOP-693]). [[a-note-on-predicates]] -A Note on Predicates --------------------- +== A Note on Predicates A `P` is a predicate of the form `Function<Object,Boolean>`. That is, given some object, return true or false. The provided predicates are outlined in the table below and are used in various steps such as <<has-step,`has()`>>-step, @@ -2584,8 +2507,7 @@ NOTE: It is possible for graph system providers and users to extend `P` and prov `regex(pattern)` could be a graph system specific `P`. [[a-note-on-barrier-steps]] -A Note on Barrier Steps ------------------------ +== A Note on Barrier Steps image:barrier.png[width=165,float=right] Gremlin is primarily a link:http://en.wikipedia.org/wiki/Lazy_evaluation[lazy], stream processing language. This means that Gremlin fully @@ -2611,8 +2533,7 @@ into a barrier collection. When there are no more traversers at the local vertex messages that are propagated to remote vertices for further processing. [[a-note-on-scopes]] -A Note on Scopes ----------------- +== A Note on Scopes The `Scope` enum has two constants: `Scope.local` and `Scope.global`. Scope determines whether the particular step being scoped is with respects to the current object (`local`) at that step or to the entire stream of objects up to that @@ -2664,8 +2585,7 @@ g.V().fold().count(local) ---- [[a-note-on-lambdas]] -A Note On Lambdas ------------------ +== A Note On Lambdas image:lambda.png[width=150,float=right] A link:http://en.wikipedia.org/wiki/Anonymous_function[lambda] is a function that can be referenced by software and thus, passed around like any other piece of data. In Gremlin, lambdas make it @@ -2707,8 +2627,7 @@ g.V().out().out().path().by('name'). <2> The length-3 paths have their objects transformed by a lambda-less step and a traversal lambda. (*good*) [[traversalstrategy]] -TraversalStrategy ------------------ +== TraversalStrategy image:traversal-strategy.png[width=125,float=right] A `TraversalStrategy` analyzes a `Traversal` and, if the traversal meets its criteria, can mutate it accordingly. Traversal strategies are executed at compile-time and form the foundation @@ -2866,8 +2785,7 @@ g.V().hasLabel('person'). <1> A collection of useful `DecorationStrategy` strategies are provided with TinkerPop3 and are generally useful to end-users. The following sub-sections detail these strategies: -ElementIdStrategy -~~~~~~~~~~~~~~~~~ +=== ElementIdStrategy `ElementIdStrategy` provides control over element identifiers. Some Graph implementations, such as TinkerGraph, allow specification of custom identifiers when creating elements: @@ -2894,8 +2812,7 @@ g.addV().property(id, '42a').id() IMPORTANT: The key that is used to store the assigned identifier should be indexed in the underlying graph database. If it is not indexed, then lookups for the elements that use these identifiers will perform a linear scan. -EventStrategy -~~~~~~~~~~~~~ +=== EventStrategy The purpose of the `EventStrategy` is to raise events to one or more `MutationListener` objects as changes to the underlying `Graph` occur within a `Traversal`. Such a strategy is useful for logging changes, triggering certain @@ -2937,8 +2854,7 @@ WARNING: `EventStrategy` is not meant for usage in tracking global mutations acr words, a mutation in one JVM process is not raised as an event in a different JVM process. In addition, events are not raised when mutations occur outside of the `Traversal` context. -PartitionStrategy -~~~~~~~~~~~~~~~~~ +=== PartitionStrategy image::partition-graph.png[width=325] @@ -2978,14 +2894,12 @@ By writing elements to particular partitions and then restricting read partition multiple graphs within a single address space. Moreover, by supporting references between partitions, it is possible to merge those multiple graphs (i.e. join partitions). -ReadOnlyStrategy -~~~~~~~~~~~~~~~~ +=== ReadOnlyStrategy `ReadOnlyStrategy` is largely self-explanatory. A `Traversal` that has this strategy applied will throw an `IllegalStateException` if the `Traversal` has any mutating steps within it. -SubgraphStrategy -~~~~~~~~~~~~~~~~ +=== SubgraphStrategy `SubgraphStrategy` is similar to `PartitionStrategy` in that it constrains a `Traversal` to certain vertices, edges, and vertex properties as determined by a `Traversal`-based criterion defined individually for each. @@ -3030,8 +2944,7 @@ g.V().outE().inV(). ---- [[dsl]] -Domain Specific Languages -------------------------- +== Domain Specific Languages Gremlin is a link:http://en.wikipedia.org/wiki/Domain-specific_language[domain specific language] (DSL) for traversing graphs. It operates in the language of vertices, edges and properties. Typically, applications built with Gremlin are @@ -3085,8 +2998,7 @@ The following sections explain how to develop application specific DSLs for diff using the examples above of the Social DSL as the API for the implementation. [[gremlin-java-dsl]] -Gremlin-Java -~~~~~~~~~~~~ +=== Gremlin-Java Creating a DSL in Java requires the `@GremlinDsl` Java annotation in `gremlin-core`. This annotation should be applied to a "DSL interface" that extends `GraphTraversal.Admin`. @@ -3208,8 +3120,7 @@ social.persons("marko").knows("josh"); NOTE: Using Maven, as shown in the `gremlin-archetype-dsl` module, makes developing DSLs with the annotation processor straightforward in that it sets up appropriate paths to the generated code automatically. -Gremlin-Python -~~~~~~~~~~~~~~ +=== Gremlin-Python Writing a Gremlin DSL in Python simply requires direct extension of several classes: http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/tutorials/getting-started/index.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/tutorials/getting-started/index.asciidoc b/docs/src/tutorials/getting-started/index.asciidoc index bc906cb..4d882ef 100644 --- a/docs/src/tutorials/getting-started/index.asciidoc +++ b/docs/src/tutorials/getting-started/index.asciidoc @@ -19,8 +19,7 @@ image::apache-tinkerpop-logo.png[width=500,link="http://tinkerpop.apache.org"] *x.y.z* -Getting Started ---------------- +== Getting Started link:http://tinkerpop.apache.org[Apache TinkerPop] is an open source Graph Computing Framework. Within itself, TinkerPop represents a large collection of capabilities and technologies and, in its wider ecosystem, an additionally extended @@ -35,8 +34,7 @@ TinkerPop Workout - by Gremlin_! image::gremlin-gym.png[width=1024] -The First Five Minutes ----------------------- +== The First Five Minutes It is quite possible to learn a lot in just five minutes with TinkerPop, but before doing so, a proper introduction of your trainer is in order. Meet Gremlin! @@ -160,8 +158,7 @@ In this first five minutes with Gremlin, you've gotten the Gremlin Console insta scratched the surface of what there is to know, but those accomplishments will help enable your understanding of the more detailed sections to come. -The Next Fifteen Minutes ------------------------- +== The Next Fifteen Minutes In the first five minutes of _The TinkerPop Workout - by Gremlin_, you learned some basics for traversing graphs. Of course, there wasn't much discussion about what a graph is. A graph is a collection of vertices (i.e. nodes, dots) @@ -191,8 +188,7 @@ image:modern-edge-1-to-3-3.png[width=325] This model is referred to as a _property graph_ and it provides a flexible and intuitive way in which to model your data. -Creating a Graph -~~~~~~~~~~~~~~~~ +=== Creating a Graph As intuitive as it is to you, it is perhaps more intuitive to Gremlin himself, as vertices, edges and properties make up the very elements of his existence. It is indeed helpful to think of our friend, Gremlin, moving about a graph when @@ -234,8 +230,7 @@ Finally, the label for an `Edge` is required and is thus part of the method sign parameter supplied, followed by the `Vertex` to which `v1` should be connected. Therefore, this usage of `addEdge` is creating an edge that goes _out_ of `v1` and into `v2` with a label of "created". -Graph Traversal - Staying Simple -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +=== Graph Traversal - Staying Simple Now that Gremlin knows where the graph data is, you can ask him to get you some data from it by doing a traversal, which you can think of as executing some link:http://tinkerpop.apache.org/docs/x.y.z/reference/#_the_graph_process[process] @@ -325,8 +320,7 @@ You should now be able to see the connection Gremlin has to the structure of the vertices to edges and so on. Your ability to string together steps to ask Gremlin to do more complex things, depends on your understanding of these basic concepts. -Graph Traversal - Increasing Complexity -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +=== Graph Traversal - Increasing Complexity Armed with the knowledge from the previous section, let's ask Gremlin to perform some more difficult traversal tasks. There's not much more that can be done with the "baby" graph we had, so let's return to the "modern" toy graph from @@ -446,15 +440,13 @@ You also learned how to envision Gremlin moving about a graph and how to use som utilized traversal steps. You are now ready to think about TinkerPop in terms of its wider applicability to graph computing. -The Final Ten Minutes ---------------------- +== The Final Ten Minutes In these final ten minutes of _The TinkerPop Workout - by Gremlin_ we'll look at TinkerPop from a higher level and introduce different features of the stack in order to orient you with what it offers. In this way, you can identify areas of interest and dig into the details from there. -Why TinkerPop? -~~~~~~~~~~~~~~ +=== Why TinkerPop? image:provider-integration.png[float=right,width=350] The goal of TinkerPop, as a Graph Computing Framework, is to make it easy for developers to create graph applications by providing APIs and tools that simplify their endeavors. One of @@ -482,8 +474,7 @@ features in this section on link:http://tinkerpop.apache.org/docs/x.y.z/referenc TIP: To maintain an abstraction over `Graph` creation use `GraphFactory.open()` to construct new instances. See the documentation for individual `Graph` implementations to learn about the configuration options to provide. -Loading Data -~~~~~~~~~~~~ +=== Loading Data image:gremlin-to-the-7.png[width=100,float=left] There are many strategies for getting data into your graph. As you are just getting started, let's look at the more simple methods aimed at "smaller" graphs. A "small" graph, in this @@ -540,8 +531,7 @@ To load larger data sets you should read about the link:http://tinkerpop.apache.org/docs/x.y.z/reference/#bulkloadervertexprogram[BulkLoaderVertexProgram] (BLVP), which provides a generalized method for loading graphs of virtually any size. -Gremlin Server -~~~~~~~~~~~~~~ +=== Gremlin Server image:gremlin-server-protocol.png[width=325,float=right] link:http://tinkerpop.apache.org/docs/x.y.z/reference/#gremlin-server[Gremlin Server] provides a way to remotely execute Gremlin scripts against one or more `Graph` instances hosted within it. It does @@ -601,8 +591,7 @@ there are drivers developed by both TinkerPop and third-parties for other link:h such as Python, Javascript, etc. Gremlin Server therefore represents the method by which non-JVM languages can interact with TinkerPop. -Conclusion -~~~~~~~~~~ +=== Conclusion ...and that is the end of _The TinkerPop Workout - by Gremlin_. You are hopefully feeling more confident in your TinkerPop skills and have a good overview of what the stack has to offer, as well as some entry points to further http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/tutorials/gremlin-language-variants/index.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/tutorials/gremlin-language-variants/index.asciidoc b/docs/src/tutorials/gremlin-language-variants/index.asciidoc index 3e760c0..00a0eac 100644 --- a/docs/src/tutorials/gremlin-language-variants/index.asciidoc +++ b/docs/src/tutorials/gremlin-language-variants/index.asciidoc @@ -19,8 +19,7 @@ image::apache-tinkerpop-logo.png[width=500,link="http://tinkerpop.apache.org"] *x.y.z* -Gremlin Language Variants -------------------------- +== Gremlin Language Variants Gremlin is an embeddable query language that can be represented using the constructs of a host programming language. Any programming language that supports link:https://en.wikipedia.org/wiki/Function_composition[function composition] @@ -124,15 +123,13 @@ construct a Gremlin language variant. Apache TinkerPop distributes with a full f that uses many of the techniques presented in this tutorial. [[language-drivers-vs-language-variants]] -Language Drivers vs. Language Variants --------------------------------------- +== Language Drivers vs. Language Variants Before discussing how to implement a Gremlin language variant in Python, it is necessary to understand two concepts related to Gremlin language development. There is a difference between a _language driver_ and a _language variant_ and it is important that these two concepts (and their respective implementations) remain separate. -Language Drivers -~~~~~~~~~~~~~~~~ +=== Language Drivers image:language-drivers.png[width=375,float=right] A Gremlin language driver is a software library that is able to communicate with a TinkerPop-enabled graph system whether directly via the JVM or indirectly via @@ -151,8 +148,7 @@ NOTE: `GraphTraversal` is a particular Gremlin domain-specific language (link:ht albeit the most popular and foundational DSL. If another DSL is created, then the same techniques discussed in this tutorial for `GraphTraversal` apply to `XXXTraversal`. -Language Variants -~~~~~~~~~~~~~~~~~ +=== Language Variants image:language-variants.png[width=375,float=right] A Gremlin language variant is a software library that allows a developer to write a Gremlin traversal within their native programming language. The language variant is responsible for @@ -187,12 +183,10 @@ IMPORTANT: The term "Gremlin-Java" denotes the language that is defined by `Grap and `__`. These three classes exist in `org.apache.tinkerpop.gremlin.process.traversal.dsl.graph` and form the definitive representation of the Gremlin traversal language. -Gremlin-Jython and Gremlin-Python ---------------------------------- +== Gremlin-Jython and Gremlin-Python [[using-jython-and-the-jvm]] -Using Jython and the JVM -~~~~~~~~~~~~~~~~~~~~~~~~ +=== Using Jython and the JVM image:jython-logo.png[width=200,float=left,link="http://www.jython.org/"] link:http://www.jython.org/[Jython] provides a link:https://www.jcp.org/en/jsr/detail?id=223[JSR-223] `ScriptEngine` implementation that enables the evaluation of @@ -245,8 +239,7 @@ link:https://en.wikipedia.org/wiki/Nashorn_(JavaScript_engine)[JavaScript], link link:http://www.scala-lang.org/[Scala], Lisp (link:https://clojure.org/[Clojure]), link:http://jruby.org/[Ruby], etc. A list of implementations is provided link:https://en.wikipedia.org/wiki/List_of_JVM_languages[here]. -Traversal Wrappers -^^^^^^^^^^^^^^^^^^ +==== Traversal Wrappers While it is possible to simply interact with Java classes in a `ScriptEngine` implementation, such Gremlin language variants will not leverage the unique features of the host language. It is for this reason that JVM-based language variants such as @@ -284,8 +277,7 @@ is desired, the language variant designer should submit a proposal to link:http: to have the extension added to a future release of Gremlin. [[using-python-and-remoteconnection]] -Using Python and RemoteConnection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +=== Using Python and RemoteConnection image:python-logo.png[width=125,float=left,link="https://www.python.org/"] The JVM is a powerful piece of technology that has, over the years, become a meeting ground for developers from numerous language communities. However, not all applications will use the JVM. @@ -574,8 +566,7 @@ Type "help", "copyright", "credits" or "license" for more information. IMPORTANT: Learn more about Apache TinkerPop's distribution of Gremlin-Python link:http://tinkerpop.apache.org/docs/x.y.z/reference/#gremlin-python[here]. [[gremlin-language-variant-conventions]] -Gremlin Language Variant Conventions ------------------------------------- +== Gremlin Language Variant Conventions Every programming language is different and a Gremlin language variant must ride the fine line between leveraging the conventions of the host language and ensuring consistency with Gremlin-Java. A collection of conventions for navigating @@ -586,8 +577,7 @@ this dual-language bridge are provided. * If the host language does not use dot-notion for method chaining, then its method chaining convention should be used instead of going the route of operator overloading. For instance, a Gremlin-PHP implementation should do `$g->V()->out()`. * If a programming language does not support method overloading, then varargs and type introspection should be used. In Gremlin-Python, `*args` does just that. -Conclusion ----------- +== Conclusion Gremlin is a simple language because it uses two fundamental programming language constructs: *function composition* and *function nesting*. Because of this foundation, it is relatively easy to implement Gremlin in any modern programming http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/tutorials/the-gremlin-console/index.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/tutorials/the-gremlin-console/index.asciidoc b/docs/src/tutorials/the-gremlin-console/index.asciidoc index fa3cb7d..506d882 100644 --- a/docs/src/tutorials/the-gremlin-console/index.asciidoc +++ b/docs/src/tutorials/the-gremlin-console/index.asciidoc @@ -19,8 +19,7 @@ image::apache-tinkerpop-logo.png[width=500,link="http://tinkerpop.apache.org"] *x.y.z* -The Gremlin Console -------------------- +== The Gremlin Console In link:http://tinkerpop.apache.org/docs/x.y.z/tutorials/getting-started/#_the_first_five_minutes["The First Five Minutes"] of the link:http://tinkerpop.apache.org[Apache TinkerPop] tutorial on how to @@ -55,8 +54,7 @@ The following points summarize the key features discussed in each use case: ** Deciding when to use the <<def-usage,def>> keyword [[learning-tool]] -Use Case: A Learning Tool -------------------------- +== Use Case: A Learning Tool image:gremlin-grad.png[float=left,width=185] __You are a new user of Apache TinkerPop and perhaps new to graphs as well. You're trying to get familiar with how Gremlin works and how it might fit into your project. You want some "quick @@ -164,8 +162,7 @@ in the console. Trying these examples for yourself and modifying their execution a good way to go about your Gremlin education. [[application-devs]] -Use Case: Application Development ---------------------------------- +== Use Case: Application Development image:gremlin-working-on-tinkerpop.png[width=350,float=right] __You are an application developer and the TinkerPop stack will be central to your application architecture. You need to develop a series of services that will execute queries @@ -386,8 +383,7 @@ only recall the rules of iteration when you move code between them. It is equall iteration. Keeping these semantics in mind will save you from many annoying debugging sessions. [[ad-hoc]] -Use Case: Ad-hoc Analysis -------------------------- +== Use Case: Ad-hoc Analysis __You are doing some general analysis on a graph with Gremlin and decide that you'd like to store those results in link:http://cassandra.apache.org/[Apache Cassandra] for additional analysis with other tools.__ @@ -652,9 +648,8 @@ You could just as easily `:install` libraries to read data from link:https://en. into a graph, use functions from link:https://commons.apache.org/proper/commons-math/[Commons Math], or do anything else you can think of with available JVM libraries. -Summary -------- +== Summary These use cases have tried to demonstrate some of the common ways in which you can use the Gremlin Console. In the process, they exposed tips and pitfalls to be aware of when working with it. Hopefully, you have gained some new -knowledge on what the console can do for you and have been inspired to work with it in more productive ways. \ No newline at end of file +knowledge on what the console can do for you and have been inspired to work with it in more productive ways. http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/upgrade/index.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/upgrade/index.asciidoc b/docs/src/upgrade/index.asciidoc index a12442b..54caa12 100644 --- a/docs/src/upgrade/index.asciidoc +++ b/docs/src/upgrade/index.asciidoc @@ -18,8 +18,7 @@ image::apache-tinkerpop-logo.png[width=500,link="http://tinkerpop.apache.org"] :toc-position: left -TinkerPop Upgrade Information -============================= += TinkerPop Upgrade Information This document helps users of TinkerPop to understand the changes that come with each software release. It outlines new features, how to resolve breaking changes and other information specific to a release. This document is useful @@ -39,4 +38,4 @@ include::release-3.2.x-incubating.asciidoc[] include::release-3.1.x-incubating.asciidoc[] -include::release-3.0.x-incubating.asciidoc[] \ No newline at end of file +include::release-3.0.x-incubating.asciidoc[] http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/cff12774/docs/src/upgrade/release-3.0.x-incubating.asciidoc ---------------------------------------------------------------------- diff --git a/docs/src/upgrade/release-3.0.x-incubating.asciidoc b/docs/src/upgrade/release-3.0.x-incubating.asciidoc index 1d5be4d..6a14931 100644 --- a/docs/src/upgrade/release-3.0.x-incubating.asciidoc +++ b/docs/src/upgrade/release-3.0.x-incubating.asciidoc @@ -15,25 +15,21 @@ See the License for the specific language governing permissions and limitations under the License. //// -TinkerPop 3.0.0 -=============== += TinkerPop 3.0.0 image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/images/gremlin-hindu.png[width=225] *A Gremlin RÄga in 7/16 Time* -TinkerPop 3.0.2 ---------------- +== TinkerPop 3.0.2 *Release Date: October 19, 2015* Please see the link:https://github.com/apache/tinkerpop/blob/3.0.2-incubating/CHANGELOG.asciidoc#tinkerpop-302-release-date-october-19-2015[changelog] for a complete list of all the modifications that are part of this release. -Upgrading for Users -~~~~~~~~~~~~~~~~~~~ +=== Upgrading for Users -BulkLoaderVertexProgram (BLVP) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +==== BulkLoaderVertexProgram (BLVP) `BulkLoaderVertexProgram` now supports arbitrary inputs (i addition to `HadoopGraph`, which was already supported in version 3.0.1-incubating). It can now also read from any TP3 enabled graph, like `TinkerGraph` @@ -42,8 +38,7 @@ or `Neo4jGraph`. See: link:https://issues.apache.org/jira/browse/TINKERPOP-814[TINKERPOP-319], link:http://tinkerpop.apache.org/docs/3.0.2-incubating/#bulkloadervertexprogram[Reference Documentation - BLVP] -TinkerGraph -^^^^^^^^^^^ +==== TinkerGraph TinkerGraph can now be configured to support persistence, where TinkerGraph will try to load a graph from a specified location and calls to `close()` will save the graph data to that location. @@ -51,8 +46,7 @@ location and calls to `close()` will save the graph data to that location. See: link:https://issues.apache.org/jira/browse/TINKERPOP-828[TINKERPOP-828], link:http://tinkerpop.apache.org/docs/3.0.2-incubating/#_configuration[Reference Documentation - TinkerGraph] -Gremlin Driver and Server -^^^^^^^^^^^^^^^^^^^^^^^^^ +==== Gremlin Driver and Server There were a number of fixes to `gremlin-driver` that prevent protocol desynchronization when talking to Gremlin Server. @@ -68,14 +62,11 @@ link:https://issues.apache.org/jira/browse/TINKERPOP-855[TINKERPOP-855], link:https://issues.apache.org/jira/browse/TINKERPOP-870[TINKERPOP-870], link:https://issues.apache.org/jira/browse/TINKERPOP-877[TINKERPOP-877] -Upgrading for Providers -~~~~~~~~~~~~~~~~~~~~~~~ +=== Upgrading for Providers -Graph Driver Providers -^^^^^^^^^^^^^^^^^^^^^^ +==== Graph Driver Providers -Gremlin Server close Operation -++++++++++++++++++++++++++++++ +===== Gremlin Server close Operation It is important to note that this feature of the sub-protocol applies to the `SessionOpProcessor` (i.e. for session-based requests). Prior to this change, there was no way to explicitly close a session. Sessions would get @@ -85,18 +76,15 @@ explicitly and as needed. See: link:https://issues.apache.org/jira/browse/TINKERPOP-849[TINKERPOP-849], link:http://tinkerpop.apache.org/docs/3.0.2-incubating/#_opprocessors_arguments[Reference Documentation - OpProcessor] -TinkerPop 3.0.1 ---------------- +== TinkerPop 3.0.1 *Release Date: September 2, 2015* Please see the link:https://github.com/apache/tinkerpop/blob/3.0.1-incubating/CHANGELOG.asciidoc#tinkerpop-301-release-date-september-2-2015[changelog] for a complete list of all the modifications that are part of this release. -Upgrading for Users -~~~~~~~~~~~~~~~~~~~ +=== Upgrading for Users -Gremlin Server -^^^^^^^^^^^^^^ +==== Gremlin Server Gremlin Server now supports a link:https://en.wikipedia.org/wiki/Simple_Authentication_and_Security_Layer[SASL-based] (Simple Authentication and Security Layer) authentication model and a default `SimpleAuthenticator` which implements @@ -111,22 +99,18 @@ for an example. See: link:https://issues.apache.org/jira/browse/TINKERPOP-576[TINKERPOP-576] -Neo4j -^^^^^ +==== Neo4j Problems related to using `:install` to get the Neo4j plugin operating in Gremlin Console on Windows have been resolved. See: link:https://issues.apache.org/jira/browse/TINKERPOP-804[TINKERPOP-804] -Upgrading for Providers -~~~~~~~~~~~~~~~~~~~~~~~ +=== Upgrading for Providers -Graph System Providers -^^^^^^^^^^^^^^^^^^^^^^ +==== Graph System Providers -GraphFactoryClass Annotation -++++++++++++++++++++++++++++ +===== GraphFactoryClass Annotation Providers can consider the use of the new `GraphFactoryClass` annotation to specify the factory class that `GraphFactory` will use to open a new `Graph` instance. This is an optional feature and will generally help implementations that have an interface extending `Graph`. If that is the case, then this annotation can be used in the following fashion: @@ -141,8 +125,7 @@ public interface MyGraph extends Graph{ See: link:https://issues.apache.org/jira/browse/TINKERPOP-778[TINKERPOP-778] -GraphProvider.Descriptor Annotation -+++++++++++++++++++++++++++++++++++ +===== GraphProvider.Descriptor Annotation There was a change that affected providers who implemented `GraphComputer` related tests such as the `ProcessComputerSuite`. If the provider runs those tests, then edit the `GraphProvider` implementation for those suites to include the `GraphProvider.Descriptor` annotation as follows: @@ -159,18 +142,15 @@ public final class HadoopGiraphGraphProvider extends HadoopGraphProvider { See: link:https://issues.apache.org/jira/browse/TINKERPOP-690[TINKERPOP-690] for more information. -Semantics of Transaction.close() -++++++++++++++++++++++++++++++++ +===== Semantics of Transaction.close() There were some adjustments to the test suite with respect to how `Transaction.close()` was being validated. For most providers, this will generally mean checking `OptOut` annotations for test renaming problems. The error that occurs when running the test suite should make it apparent that a test name is incorrect in an `OptOut` if there are issues there. See: link:https://issues.apache.org/jira/browse/TINKERPOP-764[TINKERPOP-764] for more information. -Graph Driver Providers -^^^^^^^^^^^^^^^^^^^^^^ +==== Graph Driver Providers -Authentication -++++++++++++++ +===== Authentication Gremlin Server now supports SASL-based authentication. By default, Gremlin Server is not configured with authentication turned on and authentication is not required, so existing drivers should still work without any