我最近开始研究Hadoop,过去的经验是ETL。
现在我有一个要构建父级-子级层次结构的问题。
以下是输入-
输入
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 中实现了相同的逻辑,因此我能够将层次结构创建到预定义的级别(使用自我连接)。
但是我想知道是否可以在多达n个动态级别的Spark或Pig中实现相同的功能。
注意:父级在数字上甚至小于字母上都不必小于Child,因此应避免排序。
欣赏所有输入。
提前致谢。
最佳答案
本质上,这是关于图查询的问题。您将得到一个图形(在第一个表中为一棵分层树或一系列树,给出了树的有向边),并且您希望所有路径都具有一定深度。这个查询在图形框架(spark 1.6中的第三方程序包)中很容易表达。我会用Google举例说明(现在不能了,我在火车上)。但从本质上讲,任何重复的自我联接查询都是图形中的查询。
编辑:我回到家,这是一个代码示例,可处理您的数据并从层次结构的顶部开始查找深度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
关于sql - Hadoop层次难题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37772806/