Gremlin get all incoming and outgoing vertex, including their edges and directions

Dmitry Yudin picture Dmitry Yudin · Nov 12, 2015 · Viewed 13.9k times · Source

I spent a week at Gremlin shell trying to compose one query to get all incoming and outgoing vertexes, including their edges and directions. All i tried everything.

g.V("name","testname").bothE.as('both').select().back('both').bothV.as('bothV').select(){it.map()}

output i need is (just example structure ):

[v{'name':"testname"}]___[ine{edge_name:"nameofincomingedge"}]____[v{name:'nameofconnectedvertex']

[v{'name':"testname"}]___[oute{edge_name:"nameofoutgoingedge"}]____[v{name:'nameofconnectedvertex']

So i just whant to get 1) all Vertices with exact name , edge of each this vertex (including type inE or outE), and connected Vertex. And ideally after that i want to get their map() so i'l get complete object properties. i dont care about the output style, i just need all of information present, so i can manipulate with it after. I need this to train my Gremlin, but Neo4j examples are welcome. Thanks!

Answer

stephen mallette picture stephen mallette · Nov 13, 2015

There's a variety of ways to approach this. Here's a few ideas that will hopefully inspire you to an answer:

gremlin> g = TinkerGraphFactory.createTinkerGraph()                                                                                                        
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V('name','marko').transform{[v:it,inE:it.inE().as('e').outV().as('v').select().toList(),outE:it.outE().as('e').inV().as('v').select().toList()]}
==>{v=v[1], inE=[], outE=[[e:e[9][1-created->3], v:v[3]], [e:e[7][1-knows->2], v:v[2]], [e:e[8][1-knows->4], v:v[4]]]}

The transform converts the incoming vertex to a Map and does internal traversal over in/out edges. You could also use path as follows to get a similar output:

gremlin> g.V('name','marko').transform{[v:it,inE:it.inE().outV().path().toList().toList(),outE:it.outE().inV().path().toList()]}       
==>{v=v[1], inE=[], outE=[[v[1], e[9][1-created->3], v[3]], [v[1], e[7][1-knows->2], v[2]], [v[1], e[8][1-knows->4], v[4]]]}

I provided these answers using TinkerPop 2.x as that looked like what you were using as judged from the syntax. TinkerPop 3.x is now available and if you are just getting started, you should take a look at the latest that has to offer:

http://tinkerpop.incubator.apache.org/

Under 3.0 syntax you might do something like this:

gremlin> g.V().has('name','marko').as('a').bothE().bothV().where(neq('a')).path()
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]

I know that you wanted to know what the direction of the edge in the output but that's easy enough to detect on analysis of the path.

UPDATE: Here's the above query written with Daniel's suggestion of otherV usage:

gremlin> g.V().has('name','marko').bothE().otherV().path()
==>[v[1], e[9][1-created->3], v[3]]
==>[v[1], e[7][1-knows->2], v[2]]
==>[v[1], e[8][1-knows->4], v[4]]

To see the data from this you can use by() to pick apart each Path object - The extension to the above query applies valueMap to each piece of each Path:

gremlin> g.V().has('name','marko').bothE().otherV().path().by(__.valueMap(true)) 
==>[{label=person, name=[marko], id=1, age=[29]}, {label=created, weight=0.4, id=9}, {label=software, name=[lop], id=3, lang=[java]}]
==>[{label=person, name=[marko], id=1, age=[29]}, {label=knows, weight=0.5, id=7}, {label=person, name=[vadas], id=2, age=[27]}]
==>[{label=person, name=[marko], id=1, age=[29]}, {label=knows, weight=1.0, id=8}, {label=person, name=[josh], id=4, age=[32]}]