Запрос Hive для назначения сгруппированных ключей на основе нескольких дополнительных ключей - PullRequest
0 голосов
/ 30 августа 2018

У нас есть таблица Hive с тремя разными идентификаторами, все необязательно. В каждой строке должен быть указан как минимум один из трех идентификаторов. Если указано более одного идентификатора, это устанавливает эквивалентность между несколькими идентификаторами.

Нам необходимо назначить уникальный мастер-идентификатор каждой строке на основе эквивалентностей, установленных в любой строке. Например:

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 присутствуют и А1, и А2, мы знаем, что эти идентификаторы эквивалентны.

Аналогично, в строке 5 присутствуют и A2, и A3, мы знаем, что эти идентификаторы также эквивалентны.

Снова в строке 6 у нас есть и B1, и A2, поэтому они также эквивалентны.

В строке 7 мы имеем эквивалент между C1 и C3.

Учитывая приведенную выше информацию, A1, A2, A3 и B1 все эквивалентны. Поэтому всем строкам, содержащим любой из этих идентификаторов, должен быть присвоен один и тот же главный идентификатор, поэтому мы присвоили им один и тот же главный идентификатор («M1»). Строка 7 получает уникальный собственный идентификатор ("M2"), поскольку ни один из его идентификаторов не совпадает ни с одним другим.

Как мы можем написать запрос Hive для назначения главных идентификаторов таким образом? И если Hive не лучший инструмент для достижения этой цели, можете ли вы предложить способ использования какого-либо другого инструмента в экосистеме Hadoop для назначения основных идентификаторов для этих строк?

1 Ответ

0 голосов
/ 31 августа 2018

Вы можете решить эту проблему, представив свои идентификаторы в виде вершин и найдя подключенные компоненты. Подробнее об идее здесь , раздел 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
; 

, затем просто присоедините ваши идентификаторы с соответствующей таблицей:

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

Если некоторые идентификаторы не связаны, то нетрудно выяснить, какие из них. Надеюсь, это поможет.

...