Gremlin 3 深度路径
Gremlin 3 Paths with Depth
总的来说,我对 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 得到我想要的结果,还是我必须做一些 post- 手动处理(代码)?
它可以使用单个查询来完成,但它非常复杂,如果您刚开始使用 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
的列表最终将用于创建所需的地图结果,其中迭代索引是地图的键,组件是各自的值。
总的来说,我对 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 得到我想要的结果,还是我必须做一些 post- 手动处理(代码)?
它可以使用单个查询来完成,但它非常复杂,如果您刚开始使用 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
的列表最终将用于创建所需的地图结果,其中迭代索引是地图的键,组件是各自的值。