【问题标题】:Hive query to assign grouped keys based on multiple optional keysHive 查询以基于多个可选键分配分组键
【发布时间】:2018-08-30 19:34:02
【问题描述】:

我们有一个具有三个不同 ID 的 Hive 表,它们都是可选的。在每一行中,必须提供三个 ID 中的至少一个。如果提供了多个 ID,则这会在多个 ID 之间建立等效性。

我们需要根据在任何行中建立的等效性为每一行分配一个唯一的主 ID。例如:

Line   id1     id2     id3    masterID
--------------------------------------
(1)    A1                     M1
(2)            A2             M1
(3)                    A3     M1
(4)    A1      A2             M1
(5)            A2      A3     M1
(6)    B1      A2             M1
(7)    C1              C3     M2

因为在第 4 行,A1 和 A2 都存在,我们知道这些 ID 是等价的。

同样,在第 5 行,A2 和 A3 都存在,我们知道这些 ID 也是等价的。

再次在第 6 行,我们有 B1 和 A2,所以它们也是等价的。

在第 7 行,我们有 C1 和 C3 之间的等价。

鉴于以上信息,A1、A2、A3 和 B1 都是等价的。因此,必须为所有包含这些 ID 的行分配相同的主 ID,因此我们为它们赋予了相同的主 ID(“M1”)。第 7 行收到一个自己的唯一 ID(“M2”),因为它的两个 ID 都不匹配。

我们如何编写 Hive 查询来以这种方式分配主 ID?如果 Hive 不是完成此任务的最佳工具,您能否建议一种方法来使用 Hadoop 生态系统中的其他工具来为这些行分配主 ID?

【问题讨论】:

    标签: hadoop hive mapreduce hadoop2


    【解决方案1】:

    您可以通过将 ID 表示为顶点并查找连接的组件来解决此问题。更多关于 here 的想法,第 3.5 节。让init_table 成为您的餐桌。首先,建立一个链接表

    create table links as
    select distinct id1 as v1, id2 as v2
      from init_table
     where id1 is not null and id2 is not null
    union all 
    select distinct id1 as v1, id3 as v2
      from init_table
     where id1 is not null and id3 is not null
    union all 
    select distinct id2 as v1, id3 as v2
      from init_table
     where id2 is not null and id3 is not null
    ;
    

    接下来为每个链接生成一些数字,例如行号并执行传播:

    create table links1 as
    with temp_table as (
      select v1, v2, row_number() over () as score
        from links
    )
    , tbl1 as (
      select v1, v2, score
           , max(score) over (partition by v1) as max_1
           , max(score) over (partition by v2) as max_2
        from temp_table
    )
    select v1, v2, greatest(max_1, max_2) as unique_id
      from tbl1
    ; 
    

    然后将您的 ID 与匹配表连接起来:

    create table matching_table as
    with temp_table as (
    select v1 as id, unique_id
      from link1
    union all
    select v2 as id, unique_id
      from link1
    )
    select distinct id, unique_id
      from temp_table
    

    如果某些 ID 未耦合,则不难找出哪些 ID。 希望这会有所帮助。

    【讨论】:

    • 上面的解决方案看起来很有希望,但是很容易找到它不起作用的场景。我们尝试添加子句来覆盖剩余的未发现的等价,但总是有更多。我最终编写了一个 Java 应用程序来使用 Maps 和 Sets 的组合来执行此操作。几百万行耦合 ID 的性能还不错。
    • 只是出于好奇,你能给我一个这样的例子吗?只是为了确保我不会在这里遗漏任何东西,因为连接组件的方法似乎对于这项任务是合理的。
    猜你喜欢
    • 2017-06-30
    • 2015-05-06
    • 2014-07-23
    • 2012-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多