web-dev-qa-db-ja.com

HIVEを使用してJSON配列を解析する

次のようなテーブル(jt)に多くのjson配列が格納されています。

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

各配列はレコードです。

このテーブルを解析して、ts、id、logの3つのフィールドを持つ新しいテーブル(ログ)を取得したいと思います。 get_json_objectメソッドを使用しようとしましたが、null値しか取得できないため、このメソッドは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;
13
marlieg

explode()functionを使用します

 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は、jsonの配列を保持するjtの列です。

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"}"]
6
vijay kumar

get_json_objectはjson配列文字列をサポートしていないため、次のようにjsonオブジェクトに連結できます。

SELECT 
    get_json_object(concat(concat('{"root":', jt.value), '}'), '$.root')
FROM jt;
4
lingjue8848

JSON配列が文字列としてHiveテーブルに格納されているため、この問題に遭遇しました。

解決策は少しハックといですが、それは動作し、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配列のレコード間の区切り文字を一致させ、区切り文字を追加または変更して、文字列をjsonオブジェクトのHive配列に変換するsplit()で簡単に使用できるユニークなものにします前のソリューションで説明したように、explode()で使用します。

ここで使用されるセパレータ正規表現( "}"、 ")は元のデータセットでは機能しません...正規表現は("}、\ {")である必要があり、置換は"}である必要があります、、、、 {"例..

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