You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2016/08/05 21:25:00 UTC

tinkerpop git commit: Added new recipe for Traversal Induced Values.

Repository: tinkerpop
Updated Branches:
  refs/heads/master 8f7218d53 -> ee50a6faf


Added new recipe for Traversal Induced Values.


Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/ee50a6fa
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/ee50a6fa
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/ee50a6fa

Branch: refs/heads/master
Commit: ee50a6fafabeef14b99dee308e71d9cc98619977
Parents: 8f7218d
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Wed Aug 3 18:54:28 2016 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Thu Aug 4 06:10:40 2016 -0400

----------------------------------------------------------------------
 CHANGELOG.asciidoc                              |  1 +
 docs/src/recipes/index.asciidoc                 |  2 +
 .../recipes/traversal-induced-values.asciidoc   | 83 ++++++++++++++++++++
 3 files changed, 86 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ee50a6fa/CHANGELOG.asciidoc
----------------------------------------------------------------------
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 22d2b32..43f5cc4 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -26,6 +26,7 @@ image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 TinkerPop 3.2.2 (NOT OFFICIALLY RELEASED YET)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
+* Added new recipe for "Traversal Induced Values".
 * Fixed a potential leak of a `ReferenceCounted` resource in Gremlin Server.
 * Added class registrations for `Map.Entry` implementations to `GryoMapper`.
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ee50a6fa/docs/src/recipes/index.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/recipes/index.asciidoc b/docs/src/recipes/index.asciidoc
index 18b5c9e..67a7932 100644
--- a/docs/src/recipes/index.asciidoc
+++ b/docs/src/recipes/index.asciidoc
@@ -46,6 +46,8 @@ include::cycle-detection.asciidoc[]
 
 include::centrality.asciidoc[]
 
+include::traversal-induced-values.asciidoc[]
+
 Implementation Recipes
 ======================
 

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/ee50a6fa/docs/src/recipes/traversal-induced-values.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/recipes/traversal-induced-values.asciidoc b/docs/src/recipes/traversal-induced-values.asciidoc
new file mode 100644
index 0000000..6adefc7
--- /dev/null
+++ b/docs/src/recipes/traversal-induced-values.asciidoc
@@ -0,0 +1,83 @@
+////
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+////
+[[traversal-induced-values]]
+Traversal Induced Values
+------------------------
+
+The parameters of a `Traversal` can be known ahead of time as constants or might otherwise be passed in as dynamic
+arguments.
+
+[gremlin-groovy,modern]
+----
+g.V().has('name','marko').out('knows').has('age', gt(29)).values('name')
+----
+
+In plain language, the above Gremlin asks, "What are the names of the people who Marko knows who are over the age of
+29?". In this case, "29" is known as a constant to the traversal. Of course, if the question is changed slightly to
+instead ask, "What are the names of the people who Marko knows who are older than he is?", the hardcoding of "29" will
+no longer suffice. There are multiple ways Gremlin would allow this second question to be answered. The first is
+obvious to any programmer - use a variable:
+
+[gremlin-groovy,modern]
+----
+marko = g.V().has('name','marko').next()
+g.V(marko).out('knows').has('age', gt(marko.value('age'))).values('name')
+----
+
+The downside to this approach is that it takes two separate traversals to answer the question. Ideally, there should
+be a single traversal, that can query "marko" once, determine his `age` and then use that for the value supplied to
+filter the people he knows. In this way the _value_ for the `age` filter is _induced_ from the `Traversal` itself.
+
+[gremlin-groovy,modern]
+----
+g.V().has('name','marko').as('marko').         <1>
+  out('knows').as('friend').                   <2>
+  filter(select('marko','friend').by('age').   <3>
+         where('friend', gt('marko'))).        <4>
+  values('name')
+----
+
+<1> Find the "marko" `Vertex` and label it as "marko".
+<2> Traverse out on the "knows" edges to the adjacent `Vertex` and label it as "person".
+<3> Filter the incoming "person" vertices. It is within this filter, that the traversal induced values are utilized.
+The inner `select` grabs the "marko" vertex and the current "friend". The `by` modulator extracts the "age" from both
+of those vertices which yields a `Map` with two keys, "marko" and "friend", where the value of each is the "age".
+<4> The `Map` produced in the previous step can then be filtered with `where` to only return a result if the "friend"
+age is greater than the "marko" age. If this is successful, then the `filter` step from the previous line will succeed
+and allow the "friend" vertex to pass through.
+
+This traversal could also be written declaratively with `match` step as follows:
+
+[gremlin-groovy,modern]
+----
+g.V().has('name','marko').match(
+    __.as('marko').values('age').as('a'),
+    __.as('marko').out('knows').as('friend'),
+    __.as('friend').values('age').as('b')
+  ).where('b', gt('a')).select('friend').
+  values('name')
+----
+
+Traversal induced values are not just for filtering. They can also be used when writing the values of the properties
+of one `Vertex` to another:
+
+[gremlin-groovy,modern]
+----
+g.V().has('name', 'marko').as('marko').
+  out('created').property('creator', select('marko').by('name'))
+g.V().has('name', 'marko').out('created').valueMap()
+----
\ No newline at end of file