I'm new to Gremlin. I want to connect nodes "child" under the same "parent" node with "sibling" edge.
Initial state:
Expected:
Image expected: Expected Illustration
How should I write a gremlin query for this?
So given this graph
g.addV('Parent').property('name','A').as('a').
addV('Parent').property('name','B').as('b').
addV('Child').property('name','A1').as('a1').
addV('Child').property('name','A2').as('a2').
addV('Child').property('name','B1').as('b1').
addV('Child').property('name','B2').as('b2').
addE('parent-of').from('a').to('a1').
addE('parent-of').from('a').to('a2').
addE('parent-of').from('b').to('b1').
addE('parent-of').from('b').to('b2').iterate()
We can add the sibling relationships a few different ways. It really just depends on how you want to lookup the siblings. While I did not show it above, it is common in Gremlin to give each vertex a custom ID and use that to find vertices. In this example I will just look them up by name.
To find the children of each parent we can start out with a simple query such as:
g.V().hasLabel('Parent').out()
or we could use
g.V().hasLabel('Child')
Given that we have found the children we just need to extend the query to connect the ones with a common parent. There are actually a lot of ways this query can be written (I will try to revisit this answer a little later to show some other ways and discuss possible optimizations). This should give you some basic building blocks.
gremlin> g.V().hasLabel('Parent').as('p').
......1> out().as('c').
......2> addE('sibling').
......3> to(V().hasLabel('Child').where(neq('c')).where(__.in('parent-of').as('p'))
......4> )
==>e[40][24-sibling->26]
==>e[41][26-sibling->24]
==>e[42][28-sibling->30]
==>e[43][30-sibling->28]
To verify it worked
gremlin> g.V().hasLabel('Child').out('sibling').path().by('name')
==>[A1,A2]
==>[A2,A1]
==>[B1,B2]
==>[B2,B1]
In a large graph such as a big family tree this could be an expensive query and targeting specific parents or children would obviously be a good optimization.
EDITED to add:
Here is an alternative way to achieve the same goal but starting from each child and traversing back to the parent and then out to the siblings while avoiding connecting to yourself.
gremlin> g.V().hasLabel('Child').as('c').
......1> addE('sibling').
......2> to(__.in('parent-of').out('parent-of').where(neq('c')))
==>e[84][68-sibling->70]
==>e[85][70-sibling->68]
==>e[86][72-sibling->74]
==>e[87][74-sibling->72]