Как распространить значение в графике TinkerPop

Я новичок в TinkerPop, поэтому не совсем уверен, что этим занимается Gremlin или другая часть TinkerPop:

Как мне «распространить» значение через граф TinkerPop? т.е. учитывая значение свойства в одной вершине, я хочу «переместить» это значение по ребру в другую вершину или набор вершин.

Пример для этого простого графа из 3 вершин и 2 ребер, соединяющих их:

gremlin> graph = TinkerGraph.open()
==>tinkergraph[vertices:0 edges:0]
gremlin> g = graph.traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> a = g.addV('name','a','amount', 100).next()
==>v[0]
gremlin> b = g.addV('name','b','amount', 0).next()
==>v[3]
gremlin> c = g.addV('name','c','amount', 0).next()
==>v[6]
gremlin> a.addEdge('drain', b, 'factor', 0.5)
==>e[9][0-drain->3]
gremlin> b.addEdge('drain', c, 'factor', 0.1)
==>e[10][3-drain->6]
gremlin> 

Я хочу выполнить какую-то операцию на этом графике, чтобы amount в a копировалось в b, умноженное на factor на соединяющем их ребре. Например. b ['amount'] будет равно 50. Затем дальнейшее распространение c ['amount'] будет равно 5.

В идеале я хотел бы знать один оператор, который мог бы распространить значение по всей цепочке за один раз, но также оператор, который может распространить его только на первую соседнюю вершину, а затем при втором вызове распространит его на следующую вершину , так далее.

Это можно сделать просто в Gremlin, или мне нужна какая-то другая часть TinkerPop?

-Матт


person Matt Hamilton    schedule 09.12.2016    source источник


Ответы (1)


Мне удалось это сделать с помощью мешков Gremlin:

gremlin> g.withSack(a.value('amount')).
           V(a).repeat(outE('drain').sack(mult).by('factor').
                       inV().property('amount', sack())).
                until(__.outE('drain').count().is(0)).iterate()
gremlin> g.V().valueMap()
==>[amount:[100],name:[a]]
==>[amount:[50.0],name:[b]]
==>[amount:[5.00],name:[c]]

Я инициализировал «значение мешка», равное «количеству» в вершине «а», и начал обход там, итеративно проходя по краям «слива», где мы умножаем (т.е. mult) значение в мешке на свойство «множитель». по «сливным» краям. Затем мешок назначается следующей вершине через шаг property().

Обратите внимание, что вы можете контролировать «слив» (то есть, насколько далеко вниз по цепочке вы хотите зайти) с помощью соответствующей семантики цикла на repeat. Прямо сейчас он использует until() «больше нет исходящих ребер». Но вы также можете завершить работу всего на один шаг следующим образом:

gremlin> g.withSack(a.value('amount')).
           V(a).repeat(outE('drain').sack(mult).by('factor').
                       inV().property('amount', sack())).
                times(1).iterate()
gremlin> g.V().valueMap()
==>[amount:[100],name:[a]]
==>[amount:[50.0],name:[b]]
==>[amount:[0],name:[c]]
person stephen mallette    schedule 09.12.2016
comment
Потрясающе, спасибо за это! Если бы я хотел расширить общую проблему так, чтобы в каждой вершине существовала логика относительно того, распространяются ли значения или нет, и, возможно, само значение могло быть функцией нескольких свойств в вершине, я бы написал VertexProgam для запуска на GraphComputer быть подходящим вариантом? Должны ли они быть написаны на Java или они могут использовать вариант Python? - person Matt Hamilton; 09.12.2016
comment
Добавление этих дополнительных функций к вышеперечисленным не будет слишком сложным и не потребует VertexProgram. Чтобы предотвратить распространение, вам просто нужно контролировать цикл, поэтому пусть ваш until() оценивает свойства вершины, чтобы определить, должен ли он разорваться. Если вам нужна более сложная логика для увеличения мешка, есть несколько вариантов: Во-первых, вы можете связать вызовы к sack(). Во-вторых, вы можете использовать лямбда для изменения значения мешка. В конце концов, метод sack() просто принимает BiFunction, поэтому расчет может делать все, что вы хотите. "mult" - это просто вспомогательный оператор. - person stephen mallette; 09.12.2016
comment
VertexProgram экземпляры должны быть написаны на java. Они являются частью основного API и не распространяются на GLV (варианты языка Gremlin). - person stephen mallette; 09.12.2016
comment
Хорошо, спасибо за информацию. Следующая проблема, которую я пытаюсь решить, заключается в том, что вместо распространения значения по цепочке, как указано выше, я бы увеличил / уменьшил свойство в вершине на значение в свойстве края, ведущем к нему. Я напишу это как отдельный вопрос, хотя как только у меня будет еще несколько попыток. - person Matt Hamilton; 09.12.2016