使用 neo4j 建模有序树

2024-05-05

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

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

我立即想到了两种基本方法。一种是仅向每个 CHILD 关系添加索引/序数属性。另一种是与第一个孩子建立 FIRST 关系,并在每个孩子之间建立 NEXT 关系,以这种方式维持秩序。

对于这两种方法中的任何一种,似乎仍然没有任何现成的东西可以用来按正确的顺序遍历它。我认为如果我执行 FIRST/NEXT,只要我强制 neo4j 始终首先遍历 FIRST 并进行深度优先搜索,我就可以获得正确的顺序。那行得通吗?有没有更好的办法?这似乎应该是开箱即用更容易处理的事情。

UPDATE

最终我决定使用我的两个想法。子节点与索引属性具有 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 集合。


拉塞尔, 我们正在研究类似的事情,正在制作一个有序的时间树,其结构很大程度上遵循不同的 YEAR-2012->MONTH-01->DAY-21->VALUE123,并且可能在例如之间有 NEXT 关系。同年的几个月。

否则,如果您这样做,请考虑贡献它或调查其中的内容https://github.com/neo4j/graph-collections https://github.com/neo4j/graph-collections,高度赞赏那里的贡献和测试!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 neo4j 建模有序树 的相关文章

随机推荐