Я новичок в Gremlin и работаю с машинописным текстом в Azure Cosmos DB, а это значит, что мне не разрешено использовать все интересные новые функции, такие как sideEffect ...
У меня есть древовидный сценарий, в котором вершины являются родительскими по отношению к другим вершинам, но могут иметь только одного собственного родителя и человека, который работает в одной вершине.
Вот несколько примеров данных для моего графика:
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')
Теперь дерево выглядит так:
человек --- employeeAt --- ›unit1 --- parentOf ---› unit2 --- parentOf --- ›unit3
Теперь мы хотим сделать unit2 дочерним по отношению к unit3.
Ожидаемый результат после этого:
человек --- employeeAt --- ›unit1 --- parentOf ---› unit3 --- parentOf --- ›unit2
Теперь мы хотим переместить одну вершину (создав новый входящий parentOf-Edge и отбросив старую).
Первый блок - проверить, есть ли у человека доступ к обеим вершинам. Это не очень эффективно, но я не знаю, как это сделать лучше.
Первое выражение в coalesce - переместить вершину вниз по дереву (сделать ее дочерней по отношению к одной из его подчиненных вершин). Поэтому мы проверяем, является ли он родителем targetVertex, когда он является родителем, тогда он также выполняет остальную часть этого оператора coalesce.
Второе утверждение - переместить вершину в другую ветвь дерева. Это будет достигнуто, когда это не будет трудной частью.
// 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()
У меня сейчас несколько проблем:
- То, как я пытаюсь бросить, не работает
- Когда я удаляю оператор drop, он дважды создает (в первом случае слияния) оба края, что для меня совершенно не имеет смысла.
- Есть ли более эффективный способ проверить, является ли usedAt-Vertex родительским (или прародителем или кем-то еще) движущейся и целевой вершины?