我的图表包含具有不同属性类的顶点。我想过滤具有特定属性的顶点,然后对它们进行排序。以下是我的代码的样子:
class VertexProperty()
case class Property1(val name: String, val servings: Int) extends VertexProperty
case class Property2(val description: String) extends VertexProperty
val vertexArray = Array(
(1L, Property1("propertyName",8)),
(2L, Property1("propertyName",4)),
(3L, Property2("description"))
)
val edgeArray = Array(
Edge(1L, 2L, "step1"),
Edge(1L, 3L, "step2")
)
val vertexRDD: RDD[(Long, VertexProperty)] = sc.parallelize(vertexArray)
val edgeRDD: RDD[Edge[String]] = sc.parallelize(edgeArray)
val graph: Graph[VertexProperty, String] = Graph(vertexRDD, edgeRDD)
我想只使用property1获取顶点,这段代码运行正常:
val vertices = graph.vertices.filter{
case (id, vp: Property1) => vp.description != ""
case _ => false
}
结果就是这样:
(1L,Property1(" propertyName",8)),(2L,Property1(" propertyName",4))
现在,问题在于我想让这些顶点按" serves"排序。这是Property1类的第二个参数。我可以通过顶点id对此结果进行排序:
vertices.collect().sortBy(_._1).foreach(println)
但这不起作用。
vertices.collect().sortBy(_._2._2).foreach(println)
答案 0 :(得分:2)
将VertexProperty
转换为trait
(或制作父类Serializable
)
sealed trait VertexProperty
case class Property1(name: String, servings: Int) extends VertexProperty
case class Property2(description: String) extends VertexProperty
确保类型匹配:
val vertexArray: Array[(Long, VertexProperty)] = Array(
(1L, Property1("propertyName",8)),
(2L, Property1("propertyName",4)),
(3L, Property2("description"))
)
收集而不是过滤器:
val vertices: RDD[(Long, Property1)] = graph.vertices.collect {
case (id, p @ Property1(name, _)) if name != "" => (id, p)
}
结果RDD
将为RDD[(Long, Property1)]
,您可以按Property1
字段对其进行排序。
注意强>:
如果没有额外的调整,它可能无法在REPL中使用。如有必要,请参阅Case class equality in Apache Spark并按照说明操作。
collect { }
的行为与collect()
不同。第一个通过应用f返回包含所有匹配值的RDD,而最新一个收集并向驱动程序返回一个包含此RDD中所有元素的数组。
您不能sortBy(_._2._2)
,因为Property1
不是Tuple2
且没有_._2
- 它只有name
和{{1} }。此外,无需servings
:
collect