1

My use case is: Bag vertex has edge holds to Box vertex and Box vertex has edge contains to Fruit vertex. So it's a parent-child relation between 3 vertices.

Is it possible to write gremlin query which returns all related 3 vertices. for e.g i need to fetch all Bags by id including Box vertex and further down to Fruit vertex for that Bag id. In SQL like syntax it's a simple select * from bag where id = 1.

sample structure:

g.addV('bag').property('id',1).property('name','bag1').property('size','12').as('1').
  addV('box').property('id',2).property('name','box1').property('width','12').as('2').
  addV('fruit').property('id',3).property('name','apple').property('color','red').as('3').
  addV('bag').property('id',4).property('name','bag2').property('size','44').as('4').
  addV('box').property('id',5).property('name','box2').property('width','14').as('5').
  addV('fruit').property('id',6).property('name','orange').property('color','yellow').as('6').
  addE('holds').from('1').to('2').
  addE('contains').from('2').to('3').
  addE('holds').from('4').to('5').
  addE('contains').from('5').to('6').iterate()

I want to get all properties of 1, 2, 3 when i query for vertices 1.

I want the response in the below format.

"bags" : [{ "id":"1", "name":"bag1", "size" :"12", "boxes":[ { "id" : "2", "name":"box1", "width" : "12", "fruits": [{ "id":"3", "name" : "apple", "color" : "red" }] }] }, { "id":"4", "name":"bag2", "size" : "44", "boxes":[ { "id" : "5", "name":"box2", "width" : "44", "fruits": [{ "id":"6", "name" : "orange" "color" : "yellow" }] }] }]

But not sure if similar case is possible in gremlin as there are no implicit relation between vertices.

Venkata Dorisala
  • 4,783
  • 7
  • 49
  • 90

1 Answers1

4

I would probably use project() to accomplish this:

gremlin> g.V().hasLabel('bag').
......1>   project('id', 'name','boxes').
......2>     by('id').
......3>     by('name').
......4>     by(out('holds').
......5>        project('id','name','fruits').
......6>          by('id').
......7>          by('name').
......8>          by(out('contains').
......9>             project('id','name').
.....10>               by('id').
.....11>               by('name').
.....12>             fold()).
.....13>        fold())
==>[id:1,name:bag1,boxes:[[id:2,name:box1,fruits:[[id:3,name:apple]]]]]
==>[id:4,name:bag2,boxes:[[id:5,name:box2,fruits:[[id:6,name:orange]]]]]

I omitted the "bags" root level key as there were no other keys in the Map and it didn't seem useful to add that extra level.

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • Thanks @stephan. I updated my question with more data and sample response. please update your answer. – Venkata Dorisala Oct 07 '18 at 19:13
  • 1
    Nice one. If i have more properties than `id`, `name` then should include all of them as `by('xxx')`. Is there any solution to include all the properties by default ? – Venkata Dorisala Oct 08 '18 at 12:50
  • 1
    In sql you wouldn't do `SELECT * FROM table` - you would be explicit with the fields - so including them individually is typically best. there are ways to do what you're asking though - you can read about them here: http://tinkerpop.apache.org/docs/current/recipes/#collections – stephen mallette Oct 08 '18 at 13:26
  • Hi, the above query is breaking if i add any additional property to one of the vertex because previous data doesn't have that property. Any suggestion ? – Venkata Dorisala Oct 18 '18 at 13:57
  • there's a number of ways to deal with it. a simple way is to use `coalesce()` - http://tinkerpop.apache.org/docs/current/reference/#coalesce-step – stephen mallette Oct 18 '18 at 16:41