2
votes

I'm using gremlin Python to query a Neptune DB. Given a vertices, I need to return all the outward edges with their 'from' and 'to' ids, label and any other properties.

The query below

query_result = g.V().has('name', 'marco').outE().inV().path().toList()

gives me the 'from' and 'to' in a form i can parse into a list of dicts, and a value map of the edge gives me the other values but i need it returned in a single list. my ideal format is [{from: x, to: y, label: foo, property1: bar},...]

Any help greatly appreciated.

2

2 Answers

1
votes

You can do it with elementMap step:

g.V().has('name', 'marko').outE().inV().
  path().
    by(elementMap())

EDIT:

if elementMap not supported you can specify what you want to get from vertices and edges separately using by steps. there you can create any data format you want with project

g.V().has('name', 'marko').outE().inV().
  path().
    by(valueMap(true)).by(union(
      project('from', 'to').
        by(outV().id()).
        by(inV().id()),
      valueMap(true)
    ).unfold().
    group().by(keys).
      by(select(values).unfold()))

example: https://gremlify.com/ab

4
votes

You can get almost the result you need by simply projecting the results. I will add an example at the end of how to flatten it even more. You should be able to tweak this query any way you need adding more valueMap steps etc. This does not yield a single list but groups each edge with its properties, label and ID.

Note that I used valueMap(true) which is deprecated and the new form is valueMap().with(WithOptions.tokens). Either will still work currently. The advantage of this approach is that no tracking of the path is needed which in general is more efficient in terms of memory usage etc. by the query engine.

gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]

gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]

gremlin> g.V().has('name','marko').
               outE().
               project('from','edge','to').
                 by(outV()).
                 by(valueMap(true)).
                 by(inV())

==>[from:v[1],edge:[id:9,label:created,weight:0.4],to:v[3]]
==>[from:v[1],edge:[id:7,label:knows,weight:0.5],to:v[2]]
==>[from:v[1],edge:[id:8,label:knows,weight:1.0],to:v[4]]    

If you want to flatten this result into a single list you can just add a little more to the query:

gremlin> g.V().has('name','marko').
               outE().
               project('from','edge','to').
                 by(outV()).
                 by(valueMap(true)).
                 by(inV()).
               union(select('edge').unfold(),
                     project('from').by(select('from')).unfold(),
                     project('to').by(select('to')).unfold()).fold()   


[id=9,label=created,weight=0.4,from=v[1],to=v[3],id=7,label=knows,weight=0.5,from=v[1],to=v[2],id=8,label=knows,weight
=1.0,from=v[1],to=v[4]]  

Lastly if you wanted a series of such lists back rather than one big one you can wrap the union step in local scope.

gremlin> g.V().has('name','marko').
               outE().
               project('from','edge','to').
                 by(outV()).
                 by(valueMap(true)).
                 by(inV()).local(
               union(select('edge').unfold(),
                     project('from').by(select('from')).unfold(),
                     project('to').by(select('to')).unfold()).fold())      

==>[id=9,label=created,weight=0.4,from=v[1],to=v[3]]
==>[id=7,label=knows,weight=0.5,from=v[1],to=v[2]]
==>[id=8,label=knows,weight=1.0,from=v[1],to=v[4]]