Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to commit changes on gremlin server using gremlin python

I am writing a script to create a graph on gremlin-server using the gremlin-python library. I could not find any good documentation for the library.

This is the code structure with which I am experimenting:

from    gremlin_python                                  import statics
from    gremlin_python.structure.graph                  import Graph
from    gremlin_python.process.graph_traversal          import __
from    gremlin_python.process.strategies               import *
from    gremlin_python.driver.driver_remote_connection  import DriverRemoteConnection

graph = Graph()

g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','try1'))

# Drop all vertices in the graph to create a new one
g.V().drop().iterate()

a = g.addV('person').property('name', 'Tushar').property('pronoun', 'me')
b = g.addV('person').property('name', 'Avi').property('pronoun','you')

e1 = a.addE('knows').to(b).property('relation','self')

c = g.addV('subject').property('name','maths')

e2 = a.addE('studies').to(c)

e3 = b.addE('studies').to(c)
e3.next()

v = g.V().toList()
e = g.E().toList()

print(v)
print(e)

This code gives me only 2 vertices, and 1 edge.

Some of my tries :

  • When I try the code without .next(), no data gets committed on the graph.
  • When I give e1 a .next(), 2 different vertices and 1 different edge gets created
  • When I add .next() to e2 and e1, an error is thrown saying StopIteration
  • When I add .next() to e3 and e1, I get 4 vertices and 2 edges

My graph should have 3 vertices and 3 nodes. And what I really want is to commit changes made by the script on the graph.

Some additional information :

  • I am storing the graph in graphson format
  • I am using Python3.6
like image 732
Tushar Aggarwal Avatar asked Apr 13 '18 08:04

Tushar Aggarwal


People also ask

How do I add edges to my Gremlin?

Create an edge To create a new edge between two vertices, use the addEdge(v1, v2, label) method. The edge will be created with the label specified. In the example below two vertices are created and assigned to a variable (Gremlin is based on Groovy), then an edge is created between them.

How do I access the Gremlin server?

Navigate to the GREMLIN_ SERVER _HOME directory. Navigate to the bin directory. In the bin directory run is the gremlin-server. bat start file if you are on a Windows machine or the gremlin-server.sh start file if you are on Linux or a Mac.

How do you add a vertex in Gremlin?

In Gremlin nodes are referred to as “Vertexes”. To add a node/vertex to the graph, you simply use the command addV() on your graph traversal source. For consistency, most people use “g” as their default graph traversal source.


1 Answers

You need to iterate your traversals. In other words, when you make this kind of assignment:

a = g.addV('person').property('name', 'Tushar').property('pronoun', 'me') 

nothing gets sent to the server and "a" does not contain your new vertex. You've simply assigned a Traversal instance to "a" - see this demonstrated in the following in Groovy:

gremlin> t = g.addV('person').property('name','tushar').property('pronoun','me');[]
gremlin> t.class
==>class org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal
gremlin> a = t.next()
==>v[0]
gremlin> a.class
==>class org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerVertex

So, that leads to the next isssue. You are thinking "a" is a Vertex object for which you want to call addE() on, but we've already established that "a" is in fact a Traversal. In the first place, Vertex does not have an addE() method so even if that was a Vertex this approach would not work. Second, because you have a Traversal object which does have an addE() method, you're ending up with this situation demonstrated in Groovy:

gremlin> a = g.addV('person').property('name', 'Tushar').property('pronoun', 'me');[]
gremlin> b = g.addV('person').property('name', 'Avi').property('pronoun','you');[]
gremlin> 
gremlin> e1 = a.addE('knows').to(b).property('relation','self');[]
gremlin> e1.toString()
==>[AddVertexStartStep({pronoun=[me], label=[person], name=[Tushar]}), AddEdgeStep({label=[knows], ~to=[[AddVertexStartStep({pronoun=[you], label=[person], name=[Avi]})]], relation=[self]})]
gremlin> 
gremlin> c = g.addV('subject').property('name','maths');[]
gremlin> 
gremlin> e2 = a.addE('studies').to(c);[]
gremlin> e2.toString()
==>[AddVertexStartStep({pronoun=[me], label=[person], name=[Tushar]}), AddEdgeStep({label=[knows], ~to=[[AddVertexStartStep({pronoun=[you], label=[person], name=[Avi]})]], relation=[self]}), AddEdgeStep({label=[studies], ~to=[[AddVertexStartStep({label=[subject], name=[maths]})]]})]
gremlin> 
gremlin> e3 = b.addE('studies').to(c);[]
gremlin> e3.toString()
==>[AddVertexStartStep({pronoun=[you], label=[person], name=[Avi]}), AddEdgeStep({label=[studies], ~to=[[AddVertexStartStep({label=[subject], name=[maths]})]]})]
gremlin> e3.next()
==>e[8][3-studies->6]
gremlin> g.E()
==>e[8][3-studies->6]

Note the lines where I did a toString(). Again, you don't have a result there as you expect, but instead a Traversal. In each of those toString()'d traversals you can see that you've really just built a more complex traversal, embedding one within the other. Taking the first one in more detail:

gremlin> a = g.addV('person').property('name', 'Tushar').property('pronoun', 'me');[]
gremlin> b = g.addV('person').property('name', 'Avi').property('pronoun','you');[]
gremlin> e1 = a.addE('knows').to(b).property('relation','self');[]
gremlin> e1.toString()
==>[AddVertexStartStep({pronoun=[me], label=[person], name=[Tushar]}), AddEdgeStep({label=[knows], ~to=[[AddVertexStartStep({pronoun=[you], label=[person], name=[Avi]})]], relation=[self]})]

So, with those lines of code you basically constructed the traversal:

g.addV('person').property('name', 'Tushar').property('pronoun', 'me').
  addE('knows').to(addV('person').
                   property('name', 'Avi').
                   property('pronoun','you')).property('relation','self')

Then "e1" is never iterated so that data never gets added. Your code should be altered as follows for it to work:

from    gremlin_python                                  import statics
from    gremlin_python.structure.graph                  import Graph
from    gremlin_python.process.graph_traversal          import __
from    gremlin_python.process.strategies               import *
from    gremlin_python.driver.driver_remote_connection  import DriverRemoteConnection

graph = Graph()

g = graph.traversal().withRemote(DriverRemoteConnection('ws://localhost:8182/gremlin','try1'))

# Drop all vertices in the graph to create a new one
g.V().drop().iterate()

a = g.addV('person').property('name', 'Tushar').property('pronoun', 'me').next()
b = g.addV('person').property('name', 'Avi').property('pronoun','you').next()
g.addE('knows').from_(a).to(b).property('relation','self').iterate()

c = g.addV('subject').property('name','maths').next()

e2 = g.addE('studies').from_(a).to(c).next()

e3 = g.addE('studies').from_(b).to(c).next()

v = g.V().toList()
e = g.E().toList()

print(v)
print(e)

I believe the above syntax however will only work on the latest version of TinkerPop. Personally I would prefer if the above to be just written as:

gremlin> g.addV('person').property('name', 'Tushar').property('pronoun', 'me').as('a').
......1>   addV('person').property('name', 'Avi').property('pronoun','you').as('b').
......2>   addV('subject').property('name','maths').as('c').
......3>   addE('knows').from_('a').to('b').property('relation','self').
......4>   addE('studies').from_('a').to('c').
......5>   addE('studies').from_('a').to('c').iterate()
gremlin> g.E()
==>e[23][15-knows->18]
==>e[24][15-studies->21]
==>e[25][15-studies->21]

In this way, your traversal gets sent to the server once and generates all the data in a single request.

Finally, regarding:

I could not find any good documentation for the library.

You will note that I demonstrated your code in the Gremlin Console, which is Groovy based. It is a cut/paste fit. In that way, any documentation on Gremlin, and there is a lot, will be helpful to you. Please don't get distracted by the fact that the examples you come across are mostly in Groovy. The only differences are language specific syntax (e.g. Java doesn't have single quotes to represents strings, Python has a few steps that conflict with reserved words in Python so they have a underscore pinned to the end like not_). Basically, Gremlin is Gremlin in whatever language you choose to use - just learn the subtle difference in syntax and it should get easier. All that said, we hope to translate more of our documentation to have language specific syntax - you can watch this GitHub issue if you are interested in following that.

like image 192
stephen mallette Avatar answered Sep 19 '22 19:09

stephen mallette