Gremlin-查找并连接子图

问题描述

我的图包含一个无向拓扑网络数据,我的目标是建立一个查询,以查找适用于特定网络规则的所有子网络,为每个子网络创建顶点,并连接在它们之间具有路径的节点。目的是通过在一个顶点中替换每个子网-子图来最小化大图。 为了找到所有子网,我从gremlin复制中获取了“ connected components”查询 并将我的联网规则添加到停止条件中。但是现在我很难将这个子网相互连接。

在这里提供了包含PC,路由器和其他设备节点的示例图形脚本(使用不同的网络域)。查询应该通过对连接的PC进行分组来找到所有LAN,并为每个LAN返回具有其路径的其他LAN ID。

方向在此图中没有意义,子图之间的路径可能包含许多类型的节点(路由器,设备等)。
我的GraphDB是OrientDB。

Networking Graph Image

结果应如下所示:

==>LAN 1: {pcs: [1,2,3],connected LANs: [LAN 2,LAN 3]}  
==>LAN 2: {pcs: [4,5,6],connected LANs: [LAN 1]}  
==>LAN 3: {pcs: [8,7],connected LANs: [LAN 1]}  

这是查询的第一部分(查找所有子网):

g.V().hasLabel('PC').emit(cyclicPath().or().not(both())).
 repeat(__.where(without('a')).store('a').both()).until(or(cyclicPath(),hasLabel('Router'))).
 group().by(path().unfold().limit(1)).
 by(path().local(unfold().filter(hasLabel('PC')).values('id')).unfold().dedup().fold()).unfold()

我的问题是:

  1. 我可以通过遍历每个子网中的任意节点,直到到达其他子网中存在的节点,来识别子网之间的连通性。 如何用gremlin编写
  2. 如何从此查询结果中创建新图形?
  3. 在大图(例如3000万个节点)中,这种查询性能如何?

创建图形脚本:

g = Tinkergraph.open().traversal()
g.addV("PC").property("id","1").as("pc1").
addV("PC").property("id","2").as("pc2").
addV("PC").property("id","3").as("pc3").
addV("PC").property("id","4").as("pc4").
addV("PC").property("id","5").as("pc5").
addV("PC").property("id","6").as("pc6").
addV("PC").property("id","7").as("pc7").
addV("PC").property("id","8").as("pc8").
addV("Router").property("id","9").as("router1").
addV("Router").property("id","10").as("router2").
addV("Equipment").property("id","11").as("eq1").
addV("Equipment").property("id","12").as("eq2").
addV("Equipment").property("id","13").as("eq3").
addV("Equipment").property("id","14").as("eq4").
addE("Line").from("pc1").to("pc2").
addE("Line").from("pc1").to("eq3").
addE("Line").from("pc2").to("pc3").
addE("Line").from("pc3").to("eq1").
addE("Line").from("pc3").to("eq3").
addE("Line").from("pc4").to("pc5").
addE("Line").from("pc4").to("pc6").
addE("Line").from("pc5").to("pc6").
addE("Line").from("pc7").to("pc8")
addE("Line").from("router1").to("pc7").
addE("Line").from("router1").to("pc8").
addE("Line").from("router1").to("eq2").
addE("Line").from("router2").to("eq4").
addE("Line").from("eq1").to("router1").
addE("Line").from("eq3").to("router2").
addE("Line").from("eq4").to("pc4").
iterate()

解决方法

这不是一个很好的答案,因为我认为我必须跳到您的最后一个问题,而忽略三个的前两个:

在大图(例如30M个节点)中,这种查询的性能如何?

如果您修改了here中找到的“连接的组件”配方,那么我认为您将进一步阅读有关OLTP和OLAP这类查询的一般费用。我以为对于3000万个顶点,您应该查看基于OLAP的处理(与上面显示的脚本相反)。我想您也许可以在足够大且具有大量内存的机器上使用TinkerGraph / GraphComputer来完成此操作,但这可能只是SparkGraphComputer的工作,如对end of the recipe的建议。

我认为您的前两个问题似乎取决于您对第三个问题的处理方式和成功程度,并且这些最初的问题可能会变得更加集中,甚至在达到目标后可能会有所改变。也许最好尝试解决您的OLAP方法来解决“连接的组件”,然后再提出一些更具体的问题。