Вот решение, использующее Gremlin и образец данных дерева, который только что появился на список рассылки aureliusgraphs:
g = new TinkerGraph()
root = g.addVertex(['name':'root'])
c1 = g.addVertex(['name':'1', 'sortIndex':1])
c11 = g.addVertex(['name':'1.1', 'sortIndex':1])
c12 = g.addVertex(['name':'1.2', 'sortIndex':2])
c121 = g.addVertex(['name':'1.2.1','sortIndex':1])
c122 = g.addVertex(['name':'1.2.2','sortIndex':2])
c13 = g.addVertex(['name':'1.3', 'sortIndex':3])
c2 = g.addVertex(['name':'2', 'sortIndex':2])
c21 = g.addVertex(['name':'2.1', 'sortIndex':1])
c22 = g.addVertex(['name':'2.2', 'sortIndex':2])
c3 = g.addVertex(['name':'3', 'sortIndex':3])
c31 = g.addVertex(['name':'3.1', 'sortIndex':1])
c32 = g.addVertex(['name':'3.2', 'sortIndex':2])
g.addEdge(root, c1, 'has')
g.addEdge(root, c2, 'has')
g.addEdge(root, c3, 'has')
g.addEdge(c1, c11, 'has')
g.addEdge(c1, c12, 'has')
g.addEdge(c1, c13, 'has')
g.addEdge(c2, c21, 'has')
g.addEdge(c2, c22, 'has')
g.addEdge(c3, c31, 'has')
g.addEdge(c3, c32, 'has')
g.addEdge(c12, c121, 'has')
g.addEdge(c12, c122, 'has')
Приведенный выше код для инициализации графика должен быть хорошо вставлен в приглашение Gremlin. Как только граф создан, просто введите эту команду, чтобы пройти по дереву и просуммировать числовое значение (в данном случае поле sortIndex):
gremlin> total=0;root.out.sideEffect{total+=it.sortIndex}.loop(2){true}
gremlin> total
==>21
Приведенный выше код инициализирует переменную total, а затем начинает обход с вершины root, проходя наружу и затем добавляя значение поля sortIndex к сумме. Затем он зацикливает/повторяет эту операцию над деревом до тех пор, пока не исчерпает ее (последний true определяет, как долго он зацикливается).
Для удобства я использовал TinkerGraph, но этот код будет работать с Neo4j или OrientDB (я видел их как другие теги в этом вопросе), просто изменив реализацию графа следующим образом:
g = new Neo4jGraph('/tmp/neo4j')
or
g = new OrientGraph('memory:/graph')
person
stephen mallette
schedule
01.04.2013