I am new to Gremlin and working with typescript in the Azure Cosmos DB, which means I am not allowed to use all cool new features like sideEffect ...
I have a tree-like scenario, where Vertices are parentOf other Vertices but can only have one own parent and a person which is employed at one vertex.
Here is some example-data for my graph:
g.addV('person').property('partitionKey', 'person').property('accountID','1')
g.addV('unit').property('partitionKey', 'unit').property('unitID', '1')
g.addV('unit').property('partitionKey', 'unit').property('unitID', '2')
g.addV('unit').property('partitionKey', 'unit').property('unitID', '3')
g.V().has('accountID','1').as('p').V().has('unitID','1').addE('employedAt').from('p')
g.V().has('unitID','1').as('u').V().has('unitID','2').addE('parentOf').from('u')
g.V().has('unitID','2').as('u').V().has('unitID','3').addE('parentOf').from('u')
The tree now looks like:
person --- employedAt ---> unit1 --- parentOf ---> unit2 --- parentOf ---> unit3
We now want to make unit2 the child of unit3
Expected result after that:
person --- employedAt ---> unit1 --- parentOf ---> unit3 --- parentOf ---> unit2
We now want to move one vertex around (creating a new incoming parentOf-Edge and drop the old one).
The first block is to check if the person has access to both vertices. It doesn't feel very performant but I don't know how to do it better.
The first statement in coalesce is to move a Vertex down the tree (make it the child of one of his subvertices). Therefore we check if it is the parent of the targetVertex, when it is the parent, then it also does the rest of this coalesce-statement.
The second statement is to move a vertex do another branch in the tree. This will be reached, when it is not the "difficult" part.
// Get the employedAtVertex and store the employedAtVertex
g.V().has('person', 'accountID', accountID).outE('employedAt').otherV().as('employedAtVertex')
// Check if the employedAtVertex is parentOf the movingVertex and store the movingVertex
.V().has('id', movingVertexID).as('movingVertex').until(select('employedAtVertex')).repeat(__.in('parentOf'))
// Check if the employedAtVertex is parentOf the targetVertex and store the targetVertex
.V().has('id', targetVertexID).as('targetVertex').until(select('employedAtVertex')).repeat(__.in('parentOf'))
// ### Coalesce-Step (do the first part if possible, otherwise do the second part)
.coalesce(
// ### First Part: Make a vertex the children of his own children
// Check if the movingVertex is parentOf the targetVertex
select('targetVertex').until(has('id', select('movingVertex').values('id'))).repeat(__.in('parentOf'))
// Union the incoming parentOf-Edges in moving- and targetVertex and store them as edgesToDrop
.union(select('movingVertex').inE().hasLabel('parentOf'),select('targetVertex').inE().hasLabel('parentOf')).as('edgesToDrop')
// Check if the employedAtVertex is parentOf the old parent of the movingVertex and store it as oldParentVertex
.V().has('id', oldParentOfMovingVertexID).as('oldParentVertex').until(select('employedAtVertex')).repeat(__.in('parentOf'))
// Create parentOf-Edge from oldParentVertex to targetVertex
.select('targetVertex').addE('parentOf').from('oldParentVertex')
// Create parentOf-Edge from targetVertex to movingVertex
.select('movingVertex').addE('parentOf').from('targetVertex'),
// ### Second Part: Make a vertex the children of a vertex higher in the tree or in an other branch
// Get the incoming edge in movingVertex and store it as edgesToDrop
select('movingVertex').inE('parentOf').as('edgesToDrop')
// Create parentOf-Edge from targetVertex to movingVertex
.select('movingVertex').addE('parentOf').from('targetVertex'))
// ### Ende of Coalesce
// Drop the stored edgesToDrop
.select('edgesToDrop').drop()
I have a few problems now:
- The way I try to drop doesn't work
- When I delete the drop-statement it will create (in the first case of coalesce) both edges twice, which totally doesn't make sense to me.
- Is there a more performant way to check if the employedAt-Vertex is parent (or grandparent or whatever) of the moving and the targetvertex?