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 2017/05/26 12:24:44 UTC

[31/38] tinkerpop git commit: TINKERPOP-786 Added docs for gremlin-python based DSLs

TINKERPOP-786 Added docs for gremlin-python based DSLs


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

Branch: refs/heads/tp32
Commit: 3142aeeeef4a3494b6c698f5e8e57a1205973287
Parents: 628ef6e
Author: Stephen Mallette <sp...@genoprime.com>
Authored: Thu May 11 10:06:33 2017 -0400
Committer: Stephen Mallette <sp...@genoprime.com>
Committed: Tue May 16 11:02:31 2017 -0400

----------------------------------------------------------------------
 docs/src/reference/the-traversal.asciidoc       | 110 +++++++++++++++++--
 .../src/main/java/SocialTraversalDsl.java       |   2 +-
 2 files changed, 102 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3142aeee/docs/src/reference/the-traversal.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/the-traversal.asciidoc b/docs/src/reference/the-traversal.asciidoc
index ec0bed9..443004c 100644
--- a/docs/src/reference/the-traversal.asciidoc
+++ b/docs/src/reference/the-traversal.asciidoc
@@ -2946,17 +2946,17 @@ 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
-not of the graph domain, but instead model their domain within a graph. For example, the "modern" toy graph models
+not of the graph domain, but instead model their domain within a graph. For example, the
+link:http://tinkerpop.apache.org/docs/current/images/tinkerpop-modern.png["modern" toy graph] models
 software and person domain objects with the relationships between them (i.e. a person "knows" another person and a
 person "created" software).
 
-image::tinkerpop-modern.png[width=350]
-
-An analyst who wanted to find all the people who "marko" knows could write the following Gremlin:
+An analyst who wanted to find out if "marko" knows "josh" could write the following Gremlin:
 
 [source,java]
 ----
-g.V().hasLabel('person').has('name','marko').out('knows')
+g.V().hasLabel('person').has('name','marko').
+  out('knows').hasLabel('person').has('name','josh').hasNext()
 ----
 
 While this method achieves the desired answer, it requires the analyst to traverse the graph in the domain language
@@ -2965,15 +2965,35 @@ traversal might be:
 
 [source,java]
 ----
-g.persons('marko').knows()
+g.persons('marko').knows('josh').hasNext()
 ----
 
 In the statement above, the traversal is written in the language of the domain, abstracting away the underlying
-graph structure from the query. The two traversal results are equivalent and, indeed, the "Social Network DSL" produces
+graph structure from the query. The two traversal results are equivalent and, indeed, the "Social DSL" produces
 the same set of traversal steps as the "Graph DSL" thus producing equivalent strategy application and performance
 runtimes.
 
-The following sections explain how to develop application specific DSLs for different <<gremlin-variants,Gremlin Language Variants>>.
+To further the example of the Social DSL consider the following:
+
+[source,java]
+----
+// Graph DSL - find the number of persons who created at least 2 projects
+g.V().hasLabel('person').
+  where(outE("created").count().is(P.gte(2))).count()
+
+// Social DSL - find the number of persons who created at least 2 projects
+social.persons().where(createdAtLeast(2)).count()
+
+// Graph DSL - determine the age of the youngest friend "marko" has
+g.V().hasLabel('person').has('name','marko').
+  out("knows").hasLabel("person").values("age").min()
+
+// Social DSL - determine the age of the youngest friend "marko" has
+social.persons("marko").youngestFriendsAge()
+----
+
+The following sections explain how to develop application specific DSLs for different <<gremlin-variants,Gremlin Language Variants>>
+using the examples above of the Social DSL as the API for the implementation.
 
 [[gremlin-java-dsl]
 Gremlin-Java
@@ -3005,6 +3025,10 @@ public interface SocialTraversalDsl<S, E> extends GraphTraversal.Admin<S, E> {
     public default <E2 extends Number> GraphTraversal<S, E2> youngestFriendsAge() {
         return out("knows").hasLabel("person").values("age").min();
     }
+
+    public default GraphTraversal<S, Long> createdAtLeast(int number) {
+        return outE("created").count().is(P.gte(number));
+    }
 }
 ----
 
@@ -3089,7 +3113,7 @@ It is then possible to use the `persons()` method to start traversals:
 [source,java]
 ----
 SocialTraversalSource social = graph.traversal(SocialTraversalSource.class);
-social.persons().count();
+social.persons("marko").knows("josh");
 ----
 
 NOTE: Using Maven, as shown in the `gremlin-archetype-dsl` module, makes developing DSLs with the annotation processor
@@ -3097,3 +3121,71 @@ straightforward in that it sets up appropriate paths to the generated code autom
 
 Gremlin-Python
 ~~~~~~~~~~~~~~
+
+Writing a Gremlin DSL in Python simply requires direct extension of several classes:
+
+* `GraphTraversal` - which exposes the various steps used in traversal writing
+* `__` - which spawns anonymous traversals from steps
+* `GraphTraversalSource` - which spawns `GraphTraversal` instances
+
+The Social DSL based on the link:http://tinkerpop.apache.org/docs/current/images/tinkerpop-modern.png["modern" toy graph]
+might look like this:
+
+[source,python]
+----
+class SocialTraversal(GraphTraversal):
+
+    def knows(self, person_name):
+        return self.out("knows").hasLabel("person").has("name", person_name)
+
+    def youngestFriendsAge(self):
+        return self.out("knows").hasLabel("person").values("age").min()
+
+    def createdAtLeast(self, number):
+        return self.outE("created").count().is_(P.gte(number))
+
+class __(AnonymousTraversal):
+    @staticmethod
+    def knows(*args):
+        return SocialTraversal(None, None, Bytecode()).knows(*args)
+
+    @staticmethod
+    def youngestFriendsAge(*args):
+        return SocialTraversal(None, None, Bytecode()).youngestFriendsAge(*args)
+
+    @staticmethod
+    def createdAtLeast(*args):
+        return SocialTraversal(None, None, Bytecode()).createdAtLeast(*args)
+
+
+class SocialTraversalSource(GraphTraversalSource):
+
+    def __init__(self, *args, **kwargs):
+        super(SocialTraversalSource, self).__init__(*args, **kwargs)
+        self.graph_traversal = SocialTraversal
+
+    def persons(self, *args):
+        traversal = self.get_graph_traversal()
+        traversal.bytecode.add_step("V")
+        traversal.bytecode.add_step("hasLabel", "person")
+
+        if len(args) > 0:
+            traversal.bytecode.add_step("has", "name", P.within(args))
+
+        return traversal
+----
+
+NOTE: The `AnonymousTraversal` class above is just an alias for `__` as in
+`from gremlin_python.process.graph_traversal import __ as AnonymousTraversal`
+
+Using the DSL is straightforward and just requires that the graph instance know the `SocialTraversalSource` should
+be used:
+
+[source,python]
+----
+social = Graph().traversal(SocialTraversalSource).withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','g'))
+social.persons("marko").knows("josh")
+social.persons("marko").youngestFriendsAge()
+social.persons().filter(__.createdAtLeast(2)).count()
+----
+

http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/3142aeee/gremlin-archetype/gremlin-archetype-dsl/src/main/resources/archetype-resources/src/main/java/SocialTraversalDsl.java
----------------------------------------------------------------------
diff --git a/gremlin-archetype/gremlin-archetype-dsl/src/main/resources/archetype-resources/src/main/java/SocialTraversalDsl.java b/gremlin-archetype/gremlin-archetype-dsl/src/main/resources/archetype-resources/src/main/java/SocialTraversalDsl.java
index b7e4f07..7f83152 100644
--- a/gremlin-archetype/gremlin-archetype-dsl/src/main/resources/archetype-resources/src/main/java/SocialTraversalDsl.java
+++ b/gremlin-archetype/gremlin-archetype-dsl/src/main/resources/archetype-resources/src/main/java/SocialTraversalDsl.java
@@ -61,7 +61,7 @@ public interface SocialTraversalDsl<S, E> extends GraphTraversal.Admin<S, E> {
      *
      * @param number the minimum number of projects a person created
      */
-    public default GraphTraversal<S,Long> createdAtLeast(int number) {
+    public default GraphTraversal<S, Long> createdAtLeast(int number) {
         return outE("created").count().is(P.gte(number));
     }
 }