Моделирование упорядоченного дерева с помощью neo4j

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

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

у меня есть два основных подхода, о которых я думаю с головы. Один просто добавьте свойство index / ordinal к каждому дочернему отношению. Другой - иметь первые отношения с первым ребенком и следующие отношения между каждым ребенком, чтобы поддерживать порядок таким образом.

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

обновление

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

//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 ответов


Рассел, мы работаем над такими вещами, имеем упорядоченное дерево времени в работах, которое структурировано по линиям разного года-2012- > Месяц-01->день-21 - >VALUE123 и, вероятно, будет иметь следующие отношения между, например, месяцами того же года.

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


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

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