在Neo4j图数据库上执行DFS算法

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

属性节点的类型为:
 create (A:Property {value:"abc"})

如何进行深度优先搜索以便能够按照A->B->E->F->C->G->H->D->I->J的顺序打印图中的所有值。关系r是向下方向(单向)且没有属性。我尝试了link,但对我来说看起来很复杂。是否有更简单的方法在已有的Neo4j数据库上进行简单的dfc?
1个回答

3

您链接的文档详细介绍了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-> 

更新了代码以按照用户期望的输出排序遍历路径。 - dkatzel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接