如何在Spark Graphx中查找连接到特定节点的间接节点

时间:2016-03-29 01:21:05

标签: apache-spark spark-graphx

我想找到连接到特定节点的间接节点。 我尝试使用Graph的连通组件类,如下所示......

graph.connectedComponents

然而,它正在为所有图表提供..但我想要一个特定的节点。

我也试过这样做。

graph.edges.filter(_.srcId == x).map(_.dstId)

这给出了特定节点的直接节点,我必须通过仅使用RDD操作来递归它。 有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

graph.edges.filter(_.srcId == x).map(e => (e.dstId, null)).join(
  graph.collectNeighborIds(EdgeDirection.Either)
).flatMap{t => t._2._2}.collect.toSet

如果你想要比这更深入,我会使用像 Pregel API 这样的东西。从本质上讲,它允许您重复从节点到节点发送消息并聚合结果。

编辑:Pregel解决方案

我终于让迭代停止了。 编辑以下。鉴于此图:

graph.vertices.collect
res46: Array[(org.apache.spark.graphx.VertexId, Array[Long])] = Array((4,Array()), (8,Array()), (1,Array()), (9,Array()), (5,Array()), (6,Array()), (2,Array()), (3,Array()), (7,Array()))    

graph.edges.collect
res47: Array[org.apache.spark.graphx.Edge[Double]] = Array(Edge(1,2,0.0), Edge(2,3,0.0), Edge(3,4,0.0), Edge(5,6,0.0), Edge(6,7,0.0), Edge(7,8,0.0), Edge(8,9,0.0), Edge(4,2,0.0), Edge(6,9,0.0), Edge(7,9,0.0))

我们将发送类型为Array[Long]的消息 - 所有VertexIds个已连接节点的数组。消息将上行 - dstsrc发送VertexId以及所有其他下游VertexIds。如果上游节点已经知道连接,则不会发送任何消息。最终,每个节点都知道每个连接的节点,不再发送消息。

首先我们定义vprog。根据文件:

  

用户定义的顶点程序,它运行在每个顶点上并接收   入站消息并计算新的顶点值。在第一个   迭代顶点程序在所有顶点上调用并传递   默认消息。在后续迭代中,顶点程序是   仅在接收消息的那些顶点上调用。

def vprog(id: VertexId, orig: Array[Long], newly: Array[Long]) : Array[Long] = {
  (orig ++ newly).toSet.toArray
}

然后我们定义sendMsg - 已修改:已交换src& dst

  

用户提供的函数,应用于顶点的边缘   在当前迭代中收到消息

def sendMsg(trip: EdgeTriplet[Array[Long],Double]) : Iterator[(VertexId, Array[Long])] = {
  if (trip.srcAttr.intersect(trip.dstAttr ++ Array(trip.dstId)).length != (trip.dstAttr ++ Array(trip.dstId)).toSet.size) {
    Iterator((trip.srcId, (Array(trip.dstId) ++ trip.dstAttr).toSet.toArray ))
  } else Iterator.empty }

接下来我们的mergeMsg

  

用户提供的函数,它接收两个类型为A的传入消息   并将它们合并为一个类型为A的消息。此函数必须是   交换和联想,理想情况下A的大小不应该   增加。

不幸的是,我们打算在上面的最后一句中违反规则:

def mergeMsg(a: Array[Long], b: Array[Long]) : Array[Long] = {
  (a ++ b).toSet.toArray
}

然后我们运行pregel - 已修改:已移除maxIterations,默认为Int.MaxValue

val result = graph.pregel(Array[Long]())(vprog, sendMsg, mergeMsg)

你可以看看结果:

result.vertices.collect
res48: Array[(org.apache.spark.graphx.VertexId, Array[Long])] = Array((4,Array(4, 2, 3)), (8,Array(8, 9)), (1,Array(1, 2, 3, 4)), (9,Array(9)), (5,Array(5, 6, 9, 7, 8)), (6,Array(6, 7, 9, 8)), (2,Array(2, 3, 4)), (3,Array(3, 4, 2)), (7,Array(7, 8, 9)))