这个使用 STRUCT 的简单 Hive 查询的语法错误在哪里?

Where is the syntax error on this simple Hive query with STRUCT?

让我们在 Hive 中导入一个简单的 table:

hive> CREATE EXTERNAL TABLE tweets (id BIGINT, id_str STRING, user STRUCT<id:BIGINT, screen_name:STRING>)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde'
LOCATION '/projets/tweets';

OK
Time taken: 2.253 seconds

hive> describe tweets.user;

OK
id                      bigint                  from deserializer
screen_name             string                  from deserializer
Time taken: 1.151 seconds, Fetched: 2 row(s)

我无法弄清楚这里的语法错误在哪里:

hive> select user.id from tweets limit 5;
OK
Failed with exception java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: Error evaluating user.id
Time taken: 0.699 seconds

我使用的是 Hive 1.2.1 版本。

我终于找到了答案。似乎是用于 serialize/deserialize JSON 的 JAR 有问题。默认的 (Apache) 无法很好地处理我拥有的数据。

我尝试了所有这些典型的 JAR(在括号中,'ROW FORMAT SERDE' 的 class):

  • hive-json-serde-0.2.jar (org.apache.hadoop.hive.contrib.serde2.JsonSerde)
  • hive-serdes-1.0-SNAPSHOT.jar (com.cloudera.hive.serde.JSONSerDe)
  • hive-serde-1.2.1.jar (org.apache.hadoop.hive.serde2.DelimitedJSONSerDe)
  • hive-serde-1.2.1.jar (org.apache.hadoop.hive.serde2.avro.AvroSerDe)

他们都给我不同类型的错误。我把它们列在那里,这样下一个人就可以 Google 它们:

  • 异常失败 java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: 评估 user.id
  • 时出错
  • java.lang.ClassCastException: org.json.JSONObject 无法转换为 [Ljava.lang.Object;
  • 失败,异常 java.io.IOException:org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.ClassCastException: java.lang.Integer 无法转换为 java.lang.Long 异常失败
  • java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: DelimitedJSONSerDe 无法反序列化。
  • 异常失败 java.io.IOException:org.apache.hadoop.hive.serde2.avro.AvroSerdeException: 期待 AvroGenericRecordWritable

最后,工作 JAR 是 json-serde-1.3-jar-with-dependencies.jar,可以在 here 中找到。这个正在与 'STRUCT' 一起工作,甚至可以忽略一些格式错误的 JSON。我还必须使用 table 这个 class:

 ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
 WITH SERDEPROPERTIES ("ignore.malformed.json" = "true")
 LOCATION ...

如果需要,可以从 here or here 重新编译它。我尝试了第一个存储库,在添加必要的库之后,它对我来说编译得很好。最近也更新了存储库。