Моделирование упорядоченного дерева с помощью neo4j - PullRequest
6 голосов
/ 31 января 2012

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

Наивным способом создания дерева было быпросто пройдитесь по AST и скопируйте каждый узел в дереве на узел в neo4j, используя свойства для отслеживания данных токена и т. д., а затем используйте отношение CHILD для указания на дочерние узлы.Проблема в том, что когда я позже захочу пройти по дереву, мне нужно будет сделать это в правильном порядке исходного AST, но из коробки я не совсем уверен, что лучший способ сделать это.

У меня есть два основных подхода, которые я думаю над головой.Один из них - просто добавить индекс / порядковый номер в каждое отношение CHILD.Другой - иметь ПЕРВЫЕ отношения с первым ребенком и СЛЕДУЮЩИЕ отношения между каждым ребенком, чтобы поддерживать порядок таким образом.

Для любого из этих подходов все еще не кажется, что есть что-то нестандартноеможно использовать, чтобы пройти это в правильном порядке.Я думаю, что если я сделаю FIRST / NEXT, я смогу получить правильный порядок, если заставлю neo4j всегда сначала проходить FIRST и выполнять поиск в глубину.Будет ли это работать?Есть ли способ лучше?Это кажется чем-то, что должно быть обработано легче из коробки.

ОБНОВЛЕНИЕ

В конечном счете я решил использовать обе свои идеи.Дочерние узлы имеют отношение CHILD со свойством index.Первый ребенок также имеет отношение FIRST_CHILD.Узлы-братья имеют отношение NEXT_SIBLING, чтобы дать правильный порядок.После этого обход был простым:

//reusable traversal description
final private TraversalDescription AST_TRAVERSAL = Traversal.description()
    .depthFirst()
    .expand(new OrderedByTypeExpander()
        .add(RelType.FIRST_CHILD, Direction.OUTGOING)
        .add(RelType.NEXT_SIBLING, Direction.OUTGOING));

, а затем, когда мне действительно нужно было пройтись по дереву, я мог просто сделать

for(Path path : AST_TRAVERSAL.traverse(astRoot)){
    //do stuff here
}

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

Если бы я попал в нечто более изменчивое, я бы, вероятно, попробовал коллекции, предложенные Питером Нойбауэром, и, вероятно, просто создал бы класс OrderedTreeNode, указывающийна узел и использование коллекции List для детей.

Ответы [ 2 ]

1 голос
/ 20 августа 2014

В интересах любого, кто обнаружит это более чем через 2 года, наконец-то появилась библиотека, которая поддерживает временные деревья из коробки (отказ от ответственности: я один из авторов):

https://github.com/graphaware/neo4j-timetree

1 голос
/ 01 февраля 2012

Рассел, мы работаем над такими вещами, у нас есть упорядоченное временное дерево в работах, которое структурировано по линиям разных ГОД-2012-> МЕСЯЦ-01-> ДЕНЬ-21-> ЗНАЧЕНИЕ123 и, вероятно, будет иметьСЛЕДУЮЩИЕ отношения между, например, МЕСЯЦАМИ того же года.

В противном случае, если вы сделаете это, рассмотрите возможность внести свой вклад или исследовать материал в https://github.com/neo4j/graph-collections, вкладе и тестировании там, высоко ценится!

...