使用neo4j对有序树建模

时间:2012-01-31 14:09:47

标签: neo4j traversal abstract-syntax-tree ordered-tree

我刚刚开始使用neo4j,我理解图形和关系的原理,但我对某些我想要建模的结构有点麻烦。我想在编程语言项目中使用它,并存储已解析的源文件的AST。从那里开始,我计划在节点上添加大量额外的数据和关系,以帮助进行分析和工具,但基本的AST仍然有点困难。

制作树的天真方式是简单地遍历AST并将树中的每个节点复制到neo4j中的节点,使用属性来跟踪令牌数据等,然后使用CHILD关系指向子节点。问题是,当我后来想要遍历树时,我需要能够以原始AST的正确顺序执行它,但是开箱即用我不太确定最好的方法。

我有两个基本的方法,我想到了我的头脑。一种是只为每个CHILD关系添加一个索引/序数属性。另一种是与第一个孩子建立FIRST关系,并在每个孩子之间建立NEXT关系以保持这种方式。

对于这些方法中的任何一种,它似乎仍然没有任何开箱即用的东西,我可以用它以正确的顺序遍历它。我想如果我做FIRST / NEXT,我可以得到正确的顺序,只要我强迫neo4j始终首先遍历FIRST并进行深度优先搜索。那会有用吗?有没有更好的办法?这似乎是应该更容易处理的东西。

更新

最终我决定使用我的两个想法。子节点与索引属性具有CHILD关系。第一个孩子也有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
}

对于我的用例,我在创建后实际上并没有修改树结构 - 我只是执行分析并添加更多关系和属性,因此这很容易维护。如果我不得不做更多的修改,那可能会有点工作,特别是如果我想在子关系上维护索引号。因此,对于处于类似情况的其他人来说,这可能需要考虑。

如果我确实进入了一些更可变的东西,我可能会尝试Peter Neubauer建议的集合,并且可能只是创建一个指向节点的OrderedTreeNode类并为子节点使用List集合。

2 个答案:

答案 0 :(得分:1)

罗素, 我们正在研究类似的事情,在工作中有一个有序的时间树,其结构大致与YEAR-2012-> MONTH-01-> DAY-21-> VALUE123不同,可能会有NEXT关系例如同年的月份。

否则,如果您这样做,请考虑提供或调查https://github.com/neo4j/graph-collections中的内容,贡献和测试我们非常感谢!

答案 1 :(得分:1)

为了两年以后发现这一点的人的利益,终于有了一个支持时间树开箱即用的库(免责声明:我是作者之一):

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