select and arrange multiple result within single projection

50 views Asked by At

Apologies for not having sample graph.

I’ve a directed acyclic graph mapping where Multiple nodes called "greatgrandparents" have edges to "grandparents" that has edges to multiple "parents" with edges to multiple "children".

Something like,

greatgrandparent1 -> grandparent1 -> parent1 -> child1
greatgrandparent1 -> grandparent1 -> parent1-> child2 
greatgrandparent1 -> grandparent1 -> parent2 -> child3 
greatgrandparent1 -> grandparent1 -> parent2 -> child4

… So on …

I am starting from grandparent, walking up to connected greatgrandparent. Also walking down from grandparent to parent and then to connected children’s.

I need a query that will return something like below.

{‘greatgrandparent’:  ‘greatgrandparent1’ , ‘parent’ : ‘parent1’ , ‘children’ : '['child1', 'child2', …..]'}
{‘greatgrandparent’:  ‘greatgrandparent1’ , ‘parent’ : ‘parent2’ , ‘children’ : '['child3', 'child4', …..]'}
…..

….

So far I am able to get each child on separate line like this,

{‘greatgrandparent’:  ‘greatgrandparent1’ , ‘grandparent’ : ‘grandparent1’, ‘parent’ : ‘parent1’ , ‘children’ : ‘child1’}
{‘greatgrandparent’:  ‘greatgrandparent1’  ‘grandparent’ : ‘grandparent1’, ,‘parent’ : ‘parent1’ , ‘children’ : ‘child2’}
{‘greatgrandparent’:  ‘greatgrandparent1’  ‘grandparent’ : ‘grandparent1’,  ‘parent’ : ‘parent2’ , ‘children’ : ‘child3’}
{‘greatgrandparent’:  ‘greatgrandparent1’  ‘grandparent’ : ‘grandparent1’,  ‘parent’ : ‘parent2’ , ‘children’ : ‘child4}

..

How can I get all children in a list?
I am using amazon Neptune with gremlin_python.

g.V()
.has('grandparent', 'name', 'grandparent1’).as_(‘grandparent')
.repeat(timeLimit(1000).in()).until(hasLabel('greatgrandparent'))
.dedup().order().by('name').as_(‘greatgrandparent')
.select('grandparent').repeat(timeLimit(1000).out()).until(hasLabel(‘parent))
.dedup().order().by('name').as_(‘parent')
.repeat(timeLimit(1000).out()).until(hasLabel('children'))
.dedup().order().by('name').as_(‘children')
.select(‘greatgrandparent’,grandparent','parent', 'children').by(‘name’)
1

There are 1 answers

8
Kelvin Lawrence On

One way to approach this is to investigate use of path and group. To simulate the relationships (g-grandparent, grandparent, parent, children) I'm going to use airports from the air-routes data set. First of all lets look at a simple use of path starting from ZKE which will be playing the role of our great grandparent.

g.V().has('code','ZKE').
  repeat(out().simplePath()).
  times(3).
  path().
    by('code')

when run we get

1   path[ZKE, YFA, YMO, YKQ]
2   path[ZKE, YFA, YMO, YTS]

In order to preserve this relationship, but fold the children into a list, we can add a group..by to the query.

g.V().has('code','ZKE').
  repeat(out().simplePath()).
  times(3).
  path().
    by('code').
  group().
    by(limit(local,3)).
    by(tail(local).fold())

which gives us

1   {('ZKE', 'YFA', 'YMO'): ['YKQ', 'YTS']}

Perhaps using these building blocks you can achieve the results you are looking for,