java - Gremlin 3 深度路径

标签 java graph-databases gremlin tinkerpop3

总的来说,我对 Gremlin 和图形数据库是全新的。我的任务是制定一个计划,根据子图中节点存在的深度来执行任务。

到目前为止,我可以生成子图和基于该子图的路径列表。当我尝试向路径添加深度时,特别是当某些节点存在于多个路径中时,我陷入困境。您可以在这里看到我正在测试的图表:

public void generateTestGraph(){
    Vertex web  = this.sqlgGraph.addVertex(T.label, "Server", "name", "WEB");
    Vertex app  = this.sqlgGraph.addVertex(T.label, "Server", "name", "APP1");
    Vertex app2 = this.sqlgGraph.addVertex(T.label, "Server", "name", "APP2");
    Vertex app3 = this.sqlgGraph.addVertex(T.label, "Server", "name", "APP3");
    Vertex sql  = this.sqlgGraph.addVertex(T.label, "Server", "name", "SQL");
    web.addEdge("DEPENDS_ON", app);
    web.addEdge("DEPENDS_ON", app2);
    app.addEdge("DEPENDS_ON", sql);
    app3.addEdge("DEPENDS_ON", sql);
    app2.addEdge("DEPENDS_ON", app3);

    this.sqlgGraph.tx().commit();
}

我可以像这样生成路径列表:

public void testDepGraph(){
    String name = "SQL";

    Graph subGraph = (Graph) this.sqlgGraph.traversal().V().has("name", name).repeat(__.inE("DEPENDS_ON")
    .subgraph("subGraph").outV()).in("DEPENDS_ON").loops().is(P.gt(50)).cap("subGraph").next();

    Object vl = subGraph.traversal().V().has("name", name).repeat(__.in("DEPENDS_ON")).emit(__.not(__.inE())).path().by("name").toList();
}

但是,它们看起来像这样:

{
    ["SQL", "APP1", "WEB"],
    ["SQL", "APP3", "APP2", "WEB"]
}

这很接近,但我希望看到输出如下所示:

{
    0: {"SQL"},
    1: {"APP1", "APP3"},
    2: {"APP2"},
    3: {"WEB"}
}

所以,我的问题是:我可以直接使用 Gremlin 获得我想要的结果,还是需要手动进行一些后处理(代码)?

最佳答案

可以使用单个查询来完成,但它非常复杂,如果您刚开始使用 Gremlin,可能很难掌握。

gremlin> g.V().group("x").
                 by("name").
                 by(out("DEPENDS_ON").values("name").fold()).
           barrier().
           repeat(
             cap("x").unfold().
             filter(select(values).not(unfold().where(without("y")))).
                    select(keys).where(without("y")).
             aggregate("y").
             aggregate("z").
               by(project("a","b").
                    by().
                    by(coalesce(select("z").unfold().select("b").order().by(decr).limit(1).
                                  sack(assign).sack(sum).by(constant(1)).sack(),
                                constant(0))))
           ).cap("z").unfold().group().by(select("b")).by(select("a").fold())
==>[0:[SQL],1:[APP3,APP1],2:[APP2],3:[WEB]]

此查询创建一个依赖关系映射x,然后循环遍历该映射,仅选取那些与先前迭代中处理的组件具有依赖关系的条目。一旦没有未处理的组件,repeat() 将终止。每次迭代处理后,处理后的组件将存储在名为 y 的列表中,并且相同的组件将作为元组(连同迭代索引)存储在名为 z 的列表中.

名为 z 的列表最终将用于创建所需的映射结果,其中迭代索引是映射的键,组件是各自的值。

关于java - Gremlin 3 深度路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44810880/

相关文章:

java - 使用 Titan 图数据库中的列表基数更新顶点属性的整个值

graph-databases - 如何在一次查询中遍历回 gremlin 中的根顶点

java - 想要编写动态域验证...是否可以动态声明注释@not null?

java - 如何获得完成 Activity 的剩余时间?

nosql - 可嵌入的 GraphDB?

Azure CosmosDB 使用 gremlin 控制台连接到模拟器

c# - 使用 Gremlin 遍历节点但在 Neo4J 的结果中包含起始节点

java - Jaxb:如何生成 ObjectFactory 类?

java - 动画软件中如何表示帧数据?

database - 未显示大型 Neo4j 图