0

我想在 Pig 中解析一串复杂的 JSON。具体来说,我希望 Pig 将我的 JSON 数组理解为一个包而不是单个字符数组。我发现可以使用Twitter 的 Elephant BirdMozilla 的 Akela库来解析复杂的 JSON。(我发现了一些额外的库,但我不能使用基于“加载器”的方法,因为我使用 HCatalog 加载器从 Hive 加载数据。)

但是,问题在于我的数据结构;Map 结构的每个值都包含复杂 JSON 的值部分。例如,

1. My table looks like  (WARNING: type of 'complex_data' is not STRING, a MAP of <STRING, STRING>!)
TABLE temp_table
(
    user_id BIGINT COMMENT 'user ID.',
    complex_data MAP <STRING, STRING> COMMENT 'complex json data'
)
COMMENT 'temp data.'
PARTITIONED BY(created_date STRING)
STORED AS RCFILE;


2. And 'complex_data' contains (a value that I want to get is marked with two *s, so basically #'d'#'f' from each PARSED_STRING(complex_data#'c')  )
{ "a": "[]", 
  "b": "\"sdf\"", 
  "**c**":"[{\"**d**\":{\"e\":\"sdfsdf\"
                      ,\"**f**\":\"sdfs\"
                      ,\"g\":\"qweqweqwe\"},
             \"c\":[{\"d\":21321,\"e\":\"ewrwer\"},
                   {\"d\":21321,\"e\":\"ewrwer\"},
                   {\"d\":21321,\"e\":\"ewrwer\"}]
            },
            {\"**d**\":{\"e\":\"sdfsdf\"
                      ,\"**f**\":\"sdfs\"
                      ,\"g\":\"qweqweqwe\"},
             \"c\":[{\"d\":21321,\"e\":\"ewrwer\"},
                   {\"d\":21321,\"e\":\"ewrwer\"},
                   {\"d\":21321,\"e\":\"ewrwer\"}]
            },]"
}

3. So, I tried... (same approach for Elephant Bird)

REGISTER '/path/to/akela-0.6-SNAPSHOT.jar';
DEFINE JsonTupleMap com.mozilla.pig.eval.json.JsonTupleMap();

data = LOAD temp_table USING org.apache.hive.hcatalog.pig.HCatLoader();
values_of_map = FOREACH data GENERATE complex_data#'c' AS attr:chararray;    -- IT WORKS

-- dump values_of_map shows correct chararray data per each row
-- eg) ([{"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... },
         {"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... },
         {"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... }])
       ([{"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... },
         {"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... },
         {"d":{"e":"sdfsdf","f":"sdfs","g":"sdf"},... }]) ...

attempt1 = FOREACH data GENERATE JsonTupleMap(complex_data#'c');   -- THIS LINE CAUSE AN ERROR 
attempt2 = FOREACH data GENERATE JsonTupleMap(CONCAT(CONCAT('{\\"key\\":', complex_data#'c'), '}');   -- IT ALSO DOSE NOT WORK 

我猜想“attempt1”失败了,因为该值不包含完整的 JSON。但是,当我像“attempt2”一样 CONCAT 时,我会生成额外的 \ 标记。(所以每一行都以 {\"key\":开头 )我不确定这个额外的标记是否违反了解析规则。无论如何,我想解析给定的 JSON 字符串,以便 Pig 可以理解。如果您有任何方法或解决方案,请随时告诉我。

4

1 回答 1

0

我终于通过使用带有jython UDF的jyson库解决了我的问题。我知道我可以通过使用 JAVA 或其他语言来解决它。但是,我认为 jython 和 jyson 是对这个问题最简单的答案。

于 2015-12-02T18:47:44.347 回答