将json数组导入配置单元

2vuwiymt  于 2021-06-01  发布在  Hadoop
关注(0)|答案(4)|浏览(390)

我正在尝试在配置单元中导入以下json
[{“时间”:1521115600,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:21.70905,“pm25”:16.5,“pm10”:14.60085,“气体1”:0,“气体2”:0.12,“气体3”:0,“气体4”:0,“温度”:零,“压力”:0,“湿度”:0,“噪音”:0},{“时间”:1521115659,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:24.34045,“pm25”:18.5,“pm10”:16.37065,“气体1”:0,“气体2”:0.08,“gas3”:0,“gas4”:0,“温度”:null,“压力”:0,“湿度”:0,“噪音”:0},{“时间”:1521115720,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:23.6826,“pm25”:18,“pm10”:15.9282,“gas1”:0,“gas2”:0,“gas3”:0,“gas4”:0,“温度”:null,“压力”:0,“湿度”:0,“噪音”:0},{“时间”:1521115779,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:25.65615,“pm25”:19.5,“pm10”:17.25555,“气体1”:0,“气体2”:0.04,“气体3”:0,“气体4”:0,“温度”:零,“压力”:0,“湿度”:0,“噪音”:0}]

CREATE TABLE json_serde (
 s array<struct<time: timestamp, latitude: string, longitude: string, pm1: string>>)
 ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
 WITH SERDEPROPERTIES (
     'mapping.value' = 'value'
 )
 STORED AS TEXTFILE
location '/user/hduser';

导入有效,但如果我尝试

Select * from json_serde;

它将从hadoop/user/hduser上的每个文档中只返回每个文件的第一个元素。
有一个很好的关于使用json数组的文档??

yqlxgs2m

yqlxgs2m1#

如果我可以建议你另一种方法来加载整个 JSON 将字符串作为 String 外部表中的数据类型。唯一的限制是 LINES TERMINATED BY 适当地。e、 g.如果您可以将每个json放在一行中,那么您可以创建如下表:
例如

CREATE EXTERNAL TABLE json_data_table (
    json_data String
    )   
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\u0001' LINES TERMINATED BY '\n' STORED AS TEXTFILE 
LOCATION '/path/to/json';

使用Hive get_json_object 提取单个列。此命令支持基本 xPath 比如对json字符串的查询。
如果json\u数据列有以下json字符串

{"store":
  {"fruit":\[{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}],
   "bicycle":{"price":19.95,"color":"red"}
  },
 "email":"amy@only_for_json_udf_test.net",
 "owner":"amy"
}

下面的查询获取

SELECT get_json_object(json_data, '$.owner') FROM json_data_table;

退货 amy 这样你就可以提取每一个 json 元素作为表中的列。

z5btuh9x

z5btuh9x2#

您提供的json不正确。json总是以大括号开头 "{" 最后是一个大括号 "}" . 所以,首先要注意的是你的json是错误的。
您的json应该如下所示:

{"key":[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2""},{"key1":"value1","key2":"value2"}]}

第二件事是您已经将“time”字段的数据类型声明为timestamp。但是数据(1521115600)是以毫秒为单位的。时间戳数据类型需要yyyy-mm-dd hh:mm:ss[.fffffff]格式的数据。
因此,您的数据最好采用以下格式:
{“myjson”:[{“time”:“1970-01-18 20:01:55”,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:21.70905,“pm25”:16.5,“pm10”:14.60085,“gas1”:0,“gas2”:0.12,“gas3”:0,“gas4”:0,“温度”:空,“压力”:0,“湿度”:0,“噪音”:0},“time”:“1970-01-18 20:01:55”,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:24.34045,“pm25”:18.5,“pm10”:16.37065,“gas1”:0,“gas2”:0.08,“gas3”:0,“gas4”:0,“温度”:null,“压力”:0,“湿度”:0,“噪音”:0},{“时间”:1970-01-18 20:01:55,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:23.6826,“pm25”:18,“pm10”:15.9282,“gas1”:0,“gas2”:0,“gas3”:0,“gas4”:0,“温度”:null,“压力”:0,“湿度”:0,“噪音”:0},{“时间”:“1970-01-18 20:01:55”,“纬度”:44.3959,“经度”:26.1025,“海拔”:53,“pm1”:25.65615,“pm25”:19.5,“pm10”:17.25555,“气体1”:0,“气体2”:0.04,“气体3”:0,“气体4”:0,“温度”:零,“压力”:0,“湿度”:0,“噪音”:0}}
现在,您可以使用query从表中选择记录。

hive> select * from json_serde;
OK
[{"time":"1970-01-18 20:01:55","latitude":"44.3959","longitude":"26.1025","pm1":"21.70905"},{"time":"1970-01-18 20:01:55","latitude":"44.3959","longitude":"26.1025","pm1":"24.34045"},{"time":"1970-01-18 20:01:55","latitude":"44.3959","longitude":"26.1025","pm1":"23.6826"},{"time":"1970-01-18 20:01:55","latitude":"44.3959","longitude":"26.1025","pm1":"25.65615"}]
Time taken: 0.069 seconds, Fetched: 1 row(s)
hive>

如果希望每个值分别以表格格式显示,可以使用下面的查询。

select b.* from json_serde a lateral view outer inline (a.myjson) b;

上述查询的结果如下:

+------------------------+-------------+--------------+-----------+--+
|         b.time         | b.latitude  | b.longitude  |   b.pm1   |
+------------------------+-------------+--------------+-----------+--+
| 1970-01-18 20:01:55.0  | 44.3959     | 26.1025      | 21.70905  |
| 1970-01-18 20:01:55.0  | 44.3959     | 26.1025      | 24.34045  |
| 1970-01-18 20:01:55.0  | 44.3959     | 26.1025      | 23.6826   |
| 1970-01-18 20:01:55.0  | 44.3959     | 26.1025      | 25.65615  |
+------------------------+-------------+--------------+-----------+--+

美丽的。是吗?
快乐学习。

l3zydbqr

l3zydbqr3#

如果您不能使用更新您的输入文件格式,您可以直接导入spark并使用它,一旦数据完成写回配置单元表。

scala> val myjs = spark.read.format("json").option("path","file:///root/tmp/test5").load()
myjs: org.apache.spark.sql.DataFrame = [altitude: bigint, gas1: bigint ... 13 more fields]

scala> myjs.show()
+--------+----+----+----+----+--------+--------+---------+-----+--------+--------+----+--------+-----------+----------+
|altitude|gas1|gas2|gas3|gas4|humidity|latitude|longitude|noise|     pm1|    pm10|pm25|pressure|temperature|      time|
+--------+----+----+----+----+--------+--------+---------+-----+--------+--------+----+--------+-----------+----------+
|      53|   0|0.12|   0|   0|       0| 44.3959|  26.1025|    0|21.70905|14.60085|16.5|       0|       null|1521115600|
|      53|   0|0.08|   0|   0|       0| 44.3959|  26.1025|    0|24.34045|16.37065|18.5|       0|       null|1521115659|
|      53|   0| 0.0|   0|   0|       0| 44.3959|  26.1025|    0| 23.6826| 15.9282|18.0|       0|       null|1521115720|
|      53|   0|0.04|   0|   0|       0| 44.3959|  26.1025|    0|25.65615|17.25555|19.5|       0|       null|1521115779|
+--------+----+----+----+----+--------+--------+---------+-----+--------+--------+----+--------+-----------+----------+

scala> myjs.write.json("file:///root/tmp/test_output")

或者,您可以直接配置配置单元表

scala> myjs.createOrReplaceTempView("myjs")

    scala> spark.sql("select * from myjs").show()

    scala> spark.sql("create table tax.myjs_hive as select * from myjs")
lymnna71

lymnna714#

你有一个结构数组。你贴的只有一行。
如果要查看所有元素,需要使用inline

SELECT inline(s) FROM json_table;

或者,您需要重写您的文件,以便该数组中的每个对象都是文件行中的单个json对象
另外,我在您的数据中没有看到值字段,所以我不确定您在serde属性中Map了什么

相关问题