java - 在 neo4j 图上进行 DFS

标签 java graph neo4j depth-first-search graph-traversal

我有一个具有以下结构的数据库。 enter image description here

属性节点是类型

 create (A:Property {value:"abc"})

如何做一个dfs,这样就可以把图中所有的值都打印出来。顺序是A->B->E->F->C->G->H->D-> I->J

关系 r 是向下方向(单一方向),没有属性。我试过这个 link但对我来说看起来很复杂。

有没有更简单的方法在现有的 Neo4j 数据库上做一个简单的 dfc

最佳答案

您链接到的链接非常详细,无法涵盖您可以使用 Neo4j 强大的遍历 API 执行的所有不同操作。

我想你所要做的就是:

TraversalDescription traversalDescription = graphDb.traversalDescription()
            .depthFirst()
            .relationships(YourRelationShipTypeR, Direction.OUTGOING);

    Node a = ... // however you find your node A

    try(ResourceIterator<Node> nodes =traversalDescription.traverse(a)
                                                       .nodes()
                                                       .iterator()){
        while(nodes.hasNext()){
            Node n = nodes.next();
            //or whatever property name you use to get your names for nodes
            System.out.print(n.getProperty("id") + "->");
        }

    }

应该打印 A->B->E->F->C->G->H->D->I->J->

您可以通过不在最后一个节点附加箭头来使打印语句更智能,但我会把它留给您

编辑

在自己尝试代码后,我进行了深度优先搜索,但迭代器的顺序是乱序的。似乎它任意选择了先走哪个子节点。所以我得到了类似 A->D->J->I->C->H->G->B->F->E-> 的输出.

因此您必须对 TraversalDescription 的返回路径进行排序它有一个 sort(Comparator<Path> )方法。

为了匹配您想要的遍历,我根据赋予节点名称的节点属性对路径进行排序,我将其命名为“id”。这是我更新的遍历代码:

 TraversalDescription traversalDescription = graphDb.traversalDescription()
            .depthFirst()
            .sort(new PathComparatorByName())
            .relationships(YourRelationShipTypeR, Direction.OUTGOING);

其中 PathComparatorByName 是我编写的比较器,它根据路径中遍历的节点对路径进行排序,该路径按名称按字典顺序排序:

private class PathComparatorByName implements Comparator<Path>{

    @Override
    public int compare(Path o1, Path o2) {
        Iterator<Node> iter1 = o1.nodes().iterator();
        Iterator<Node> iter2 = o2.nodes().iterator();


        while(iter1.hasNext()){
            if(!iter2.hasNext()){
                //return shorter path?
                return 1;
            }

            Node n1 = iter1.next();
            Node n2 = iter2.next();
            int nodeCmp = compareByNodeName(n1, n2);
            if(nodeCmp !=0){
                return nodeCmp;
            }

        }
        if(iter2.hasNext()){
            //return shorter path?
            return -1;
        }
        return 0;
    }

    private int compareByNodeName(Node node1, Node node2) {
        String name1 = (String)node1.getProperty("id");

         String name2 = (String)node2.getProperty("id");

        return name1.compareTo(name2);
    }

}

现在用比较器重新运行它会输出:

A->B->E->F->C->G->H->D->I->J-> 

关于java - 在 neo4j 图上进行 DFS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30863096/

相关文章:

java - 如何通过插件获取当前分支名称

python - 灯泡流 : difference between neo4jserver Graph and neo4jserver Neo4jclient

neo4j - 创建时CYPHER存储相同标签的节点关系顺序

mysql - 如何查找数据库中值之间的关系

algorithm - 检查图中的顶点是否属于循环

twitter - 构建 Twitter 用户数据库

Neo4J - 使用谓词函数的 Cypher 查询未获取所需的输出

java - 将日期和整数写入现有的 .pdf

Java:将 XML 内容写入 Excel 文件的 StringWriter

javascript - jqGrid如何根据状态数据动态填充选项列表?