我最近开始研究Hadoop,我过去的经验是在ETL上。 现在我有一个问题,我想建立父子层次结构。 以下是输入 - 的 INPUT
Parent_Id Child_Id
FAC001 FAC001
FAC001 FAC002
FAC002 FAC003
FAC003 FAC004
FAC004 FAC005
AAA005 AAA005
AAA005 AAA001
AAA001 AAA006
所需输出
Top_Parent_Id Parent_Id Child_Id Level
FAC001 FAC001 FAC001 1
FAC001 FAC001 FAC002 2
FAC001 FAC002 FAC003 3
FAC001 FAC003 FAC004 4
FAC001 FAC004 FAC005 5
AAA005 AAA005 AAA005 1
AAA005 AAA005 AAA006 2
你能否提出一个实现这个目标的方法,我已经在hive中实现了相同的逻辑,我可以将层次结构创建为预定义的级别(使用自联接)。 但我想知道是否可以在Spark或Pig中实现相同的动态级别。
注意:父母不一定要以数字或字母顺序小于Child,因此应避免订购。
感谢所有投入。
提前致谢。
答案 0 :(得分:0)
这实际上是关于图表查询的问题。给你一个图形(一个分层树,或一系列树,在你的第一个表中,给出一个树的有向边),你想要一定深度的所有路径。这个查询很容易在图形框架中表达,这是Spark 1.6中的第三方软件包。我会谷歌的例子(现在不能做,我在火车上)。但实质上,任何重复自连接的查询都是图中的查询。
编辑:我回到家中,这是一个代码示例,可以处理您的数据,并从层次结构的顶部开始查找深度为4的顶点(但是,您必须定义一个主题和每个深度/级别的查询分别):
import org.graphframes._
// define a DataFrame of vertices - one of the columns must be "id"
val vertices = sqlContext.createDataFrame(Seq(
("FAC001", 1),
("FAC002", 1),
("FAC003", 1),
("FAC004", 1),
("FAC005", 1),
("AAA001", 1),
("AAA005", 1),
("AAA006", 1)
)).toDF("id", "some_attribute")
// define a DataFrame of edges - two columns must be "src" and "dst"
val edges = sqlContext.createDataFrame(Seq(
("FAC001", "FAC002"),
("FAC002", "FAC003"),
("FAC003", "FAC004"),
("FAC004", "FAC005"),
("AAA005", "AAA001"),
("AAA001", "AAA006")
)).toDF("src", "dst")
// define a GraphFrame
val hg = GraphFrame(vertices, edges)
// roots are those vertices which have no inDegree (only outDegrees)
val roots = vertices.select("id").except(hg.inDegrees.select("id"))
// define a path of length 4
val motif = hg.find("(root1)-[]->(d1); (d1)-[]->(d2); (d2)-[]->(d3); (d3)-[]->(d4)")
// get only those paths of length 4 that start at the given root
val chain = motif.filter("root1.id = 'FAC001'").select($"root1.id".as("top_id"), $"d3.id".as("parent_id"), $"d4.id".as("child_id"))
然后在shell中尝试:
scala> chain.show
+------+---------+--------+
|top_id|parent_id|child_id|
+------+---------+--------+
|FAC001| FAC004| FAC005|
+------+---------+--------+
Graphframes是SparkSQL和DataFrames的混合体 - 你需要包含的就是包
--packages graphframes:graphframes:0.1.0-spark1.6