我最近开始研究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/

10-16 02:55