Разобрать массивы json с помощью HIVE

У меня есть много массивов json, хранящихся в таблице (jt), которая выглядит следующим образом:

[{"ts":1403781896,"id":14,"log":"show"},{"ts":1403781896,"id":14,"log":"start"}]
[{"ts":1403781911,"id":14,"log":"press"},{"ts":1403781911,"id":14,"log":"press"}]

Каждый массив является записью.

Я хотел бы проанализировать эту таблицу, чтобы получить новую таблицу (журналы) с 3 полями: TS, ID, журнал. Я пытался использовать метод get_json_object, но кажется, что метод не совместим с массивами json, потому что я получаю только нулевые значения.

Это код, который я протестировал:

CREATE TABLE logs AS 
SELECT get_json_object(jt.value, '$.ts') AS ts, 
get_json_object(jt.value, '$.id') AS id,
get_json_object(jt.value, '$.log') AS log
FROM jt;

Я пытался использовать другие функции, но они кажутся действительно сложными. Спасибо!:)

Обновить! Я решил свою проблему, выполнив регулярное выражение:

CREATE TABLE jt_reg AS
select regexp_replace(regexp_replace(value,'\\}\\,\\{','\\}\\\n\\{'),'\\[|\\]','') as valuereg  from jt;


CREATE TABLE logs AS 
SELECT get_json_object(jt_reg.valuereg, '$.ts') AS ts, 
get_json_object(jt_reg.valuereg, '$.id') AS id,
get_json_object(jt_reg.valuereg, '$.log') AS log
FROM ams_json_reg;

3 ответа

Я только столкнулся с этой проблемой, с массивом JSON, хранящимся в виде строки в таблице кустов.

Решение немного хакерское и уродливое, но оно работает и не требует serdes или внешних UDF

SELECT 
       get_json_object(single_json_table.single_json, '$.ts') AS ts,
       get_json_object(single_json_table.single_json, '$.id') AS id,
       get_json_object(single_json_table.single_json, '$.log') AS log
FROM ( SELECT explode (
  split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
            '"}","', '"}",,,,"'), ',,,,')
      ) FROM src_table) single_json_table;

Я разбил строки так, чтобы было немного легче читать. Я использую substr(), чтобы убрать первый и последний символы, удаляя [и] . Затем я использую regex_replace, чтобы сопоставить разделитель между записями в массиве json, и добавляю или изменяю разделитель, чтобы он стал чем-то уникальным, что затем можно легко использовать с split(), чтобы превратить строку в массив кустов объектов json, которые затем могут использоваться с explode(), как описано в предыдущем решении.

Обратите внимание, что используемое здесь разделительное регулярное выражение ( "}",") не будет работать с исходным набором данных... регулярное выражение должно быть ( "},\{"), а замена должна быть"},,,,{"например..

  split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
            '"},\\{"', '"},,,,{"'), ',,,,')

Используйте функцию взрыва ()

 hive (default)> CREATE TABLE logs AS
                  >   SELECT get_json_object(single_json_table.single_json, '$.ts') AS ts,
                  >   get_json_object(single_json_table.single_json, '$.id') AS id,
                  >   get_json_object(single_json_table.single_json, '$.log') AS log
                  >   FROM
                  >     (SELECT explode(json_array_col) as single_json FROM jt) single_json_table ;

Automatically selecting local only mode for query
Total MapReduce jobs = 3
Launching Job 1 out of 3
Number of reduce tasks is set to 0 since there's no reduce operator

hive (default)> select * from logs;
OK
ts      id      log
1403781896      14      show
1403781896      14      start
1403781911      14      press
1403781911      14      press
Time taken: 0.118 seconds, Fetched: 4 row(s)
hive (default)>

где json_array_col - столбец в jt, который содержит ваш массив jsons.

hive (default)> select json_array_col from jt;
json_array_col
["{"ts":1403781896,"id":14,"log":"show"}","{"ts":1403781896,"id":14,"log":"start"}"]
["{"ts":1403781911,"id":14,"log":"press"}","{"ts":1403781911,"id":14,"log":"press"}"]

Потому что get_json_object не поддерживает строку массива json, поэтому вы можете выполнить конкататацию к объекту json, например так:

SELECT 
    get_json_object(concat(concat('{"root":', jt.value), '}'), '$.root')
FROM jt;
Другие вопросы по тегам