一文速学-HiveSQL解析JSON数据详解+代码实战

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一文速学-HiveSQL解析JSON数据详解+代码实战

前言


JSON文件存储格式十分常见,在各个数据库中以及业务场景都有关于该文件的处理方式。但是有时候处理JSON文件在不同的数据库处理方法也不同,掌握一些高效的函数可以大大简化我们处理JSON数据格式的效率。面对一些复杂的存储形式,例如JSON数组存储这种就必须采取一定的处理方式,下面是处理HiveSQL解析JSON数据的函数与方法。


一、JSON数据


君欲擅其器,必先练其力。我们要对JSON文件有个熟悉的认知。


JSON是一个标记符的序列。这套标记符包含六个构造字符、字符串、数字和三个字面名。


JSON是一个序列化的对象或数组。


   数据为  键 / 值 (name/value)对;

   数据由逗号(,)分隔;

   大括号保存对象(object);

   方括号保存数组(Array);

值可以是对象、数组、数字、字符串或者三个字面值(false、null、true)中的一个。值中的字面值中的英文必须使用小写。


如:


"code":"100"


对象由花括号括起来的逗号分割的成员构成,成员是字符串键和上文所述的值由逗号分割的键值对组成:


{“code”:20,"type":"mysql"}


数组是由方括号括起来的一组值构成:


"datesource":[
    {"code":"20", "type":"mysql"},
   {"code":"20", "type":"mysql"},
    {"code":"20", "type":"mysql"}
]


二、Hive解析函数


以我们经常存储的JSON文件为实例去展示操作:

{"level":"2","time":1650973942596,"type":"0"}

HiveSQL自带两个函数可以处理JSON文件,但是一次只能处理一个JSON文件。


1.get_json_object


get_json_object的基础语法格式为:


get_json_object(json_string, '$.key')


功能:解析json的字符串json_string,返回key指定的内容。如果输入的json字符串无效,那么返回NULL。这个函数每次只能返回一个数据项。

SELECT 
GET_JSON_OBJECT('{"level":"2","time":1650973942596,"type":"0"}','$.level' ) as level ;

1b3bca4cf3f04a419a9137cc87df82be.png


如果要解析JSON的所有字段可以多写几条:

SELECT 
GET_JSON_OBJECT('{"level":"2","time":1650973942596,"type":"0"}','$.level' ) as level,
GET_JSON_OBJECT('{"level":"2","time":1650973942596,"type":"0"}','$.time' ) as times,
GET_JSON_OBJECT('{"level":"2","time":1650973942596,"type":"0"}','$.type' ) as types;

ccfc775ad92b476ab0c222b6722e5235.png


2.json_tuple


为了解决get_json_object一次解析不了整个JSON文件的问题,我们就有了json_tuple这个函数,一条便能处理一条JSON数据,基础语法为:


json_tuple(json_string, k1, k2 ...)


解析json的字符串json_string,可指定多个json数据中的key,返回对应的value。如果输入的json字符串无效,那么返回NULL。

SELECT 
json_tuple('{"level":"2","time":1650973942596,"type":"0"}','level','time','type') as (level,times,types);

9de4f9f7874f4548b23cbc9f69a1c8c0.png


但是以上这两个函数都无法处理JSON数组,需要我们使用正则替换和explode函数清洗出每条独立的JSON数据才能处理。


3.explode


explode的基础语法为:


explode(Array OR Map)


功能:explode()函数接收一个array或者map类型的数据作为输入,然后将array或map里面的元素按照每行的形式输出,即将hive一列中复杂的array或者map结构拆分成多行显示,也被称为列转行函数。

SELECT explode(array(
'
{"level":"2","time":1650973942596,"type":"0"}',
'{"level":"1","time":1650973942597,"type":"1"}',
'{"level":"3","time":1650973942598,"type":"2"}
'
))

4ed36e14418540dd9d662e075257be7c.png

select explode(map('level',1,'time',1650973942596,'type',0))

d137021b68664fa99615680d9200c8ad.png


4.regexp_replace


regexp_replace就好比python里面的sub()匹配之后替换:

基础语法:


regexp_replace(string A, string B, string C)


功能:将字符串A中的符合java正则表达式B的部分替换为C。

select REGEXP_REPLACE('{"level":"2","time":1650973942596,"type":"0"}','2','1');

dff5003d8c45442cafb222cae8435f24.png


三、Hive解析JSON数组


我们先拿到一组JSON数组:


[{"level":"2","time":1650973942596,"type":"0"},


{"level":"1","time":1650973942597,"type":"1"},


{"level":"3","time":1650973942598,"type":"2"}]


我们想要把他们转换为一下格式,变成一下这种形式:


478b5481e52141988a00bea2eacd062a.png


第一步:

第一步我们要将数组外面的,给替换掉,以免后续我们按;划分展开。

SELECT 
    REGEXP_REPLACE('[{"level":"2","time":1650973942596,"type":"0"},{"level":"1","time":1650973942597,"type":"1"},{"level":"3","time":1650973942598,"type":"2"}]','\\}\\,\\{','\\}\\;\\{')


f50e0505651947cfa83014c7205b06be.png


第二步:


将数组两边的[]给去掉:


select
REGEXP_REPLACE( 
    REGEXP_REPLACE('[{"level":"2","time":1650973942596,"type":"0"},{"level":"1","time":1650973942597,"type":"1"},{"level":"3","time":1650973942598,"type":"2"}]','\\}\\,\\{','\\}\\;\\{')
    ,'\\[|\\]','')

第三步:


按分号我们进行划分:


SELECT 
    split(
    REGEXP_REPLACE( 
    REGEXP_REPLACE('[{"level":"2","time":1650973942596,"type":"0"},{"level":"1","time":1650973942597,"type":"1"},{"level":"3","time":1650973942598,"type":"2"}]','\\}\\,\\{','\\}\\;\\{')
    ,'\\[|\\]','')
    ,'\\;')


92f2736bec474771aff02eab61ddc553.png

第四步:


之后我们便可以使用explode进行平铺了:

select 
    explode(
    split(
    REGEXP_REPLACE( 
    REGEXP_REPLACE('[{"level":"2","time":1650973942596,"type":"0"},{"level":"1","time":1650973942597,"type":"1"},{"level":"3","time":1650973942598,"type":"2"}]','\\}\\,\\{','\\}\\;\\{')
    ,'\\[|\\]','')
    ,'\\;')
    )


06721ec3998b4e12abf6892bd6e49eea.png


第五步:


最后在此表的基础之上我们再使用get_json_object或者json_tuple函数就好了:


SELECT 
      GET_JSON_OBJECT(track,'$.level') as level,
      GET_JSON_OBJECT(track,'$.time') as times,
      GET_JSON_OBJECT(track,'$.type') as types
    from (
    select 
    explode(
    split(
    REGEXP_REPLACE( 
    REGEXP_REPLACE('[{"level":"2","time":1650973942596,"type":"0"},{"level":"1","time":1650973942597,"type":"1"},{"level":"3","time":1650973942598,"type":"2"}]','\\}\\,\\{','\\}\\;\\{')
    ,'\\[|\\]','')
    ,'\\;')
    )track )track

c7d327a23d1b4741ac16f4c53ad399bf.png

目录
相关文章
|
7天前
|
数据采集 DataWorks 搜索推荐
阿里云DataWorks深度评测:实战视角下的全方位解析
在数字化转型的大潮中,高效的数据处理与分析成为企业竞争的关键。本文深入评测阿里云DataWorks,从用户画像分析最佳实践、产品体验、与竞品对比及Data Studio公测体验等多角度,全面解析其功能优势与优化空间,为企业提供宝贵参考。
57 13
|
4天前
|
数据采集 存储 JavaScript
网页爬虫技术全解析:从基础到实战
在信息爆炸的时代,网页爬虫作为数据采集的重要工具,已成为数据科学家、研究人员和开发者不可或缺的技术。本文全面解析网页爬虫的基础概念、工作原理、技术栈与工具,以及实战案例,探讨其合法性与道德问题,分享爬虫设计与实现的详细步骤,介绍优化与维护的方法,应对反爬虫机制、动态内容加载等挑战,旨在帮助读者深入理解并合理运用网页爬虫技术。
|
10天前
|
存储 监控 调度
云服务器成本优化深度解析与实战案例
本文深入探讨了云服务器成本优化的策略与实践,涵盖基本原则、具体策略及案例分析。基本原则包括以实际需求为导向、动态调整资源、成本控制为核心。具体策略涉及选择合适计费模式、优化资源配置、存储与网络配置、实施资源监控与审计、应用性能优化、利用优惠政策及考虑多云策略。文章还通过电商、制造企业和初创团队的实际案例,展示了云服务器成本优化的有效性,最后展望了未来的发展趋势,包括智能化优化、多云管理和绿色节能。
|
13天前
|
PHP 开发者 容器
PHP命名空间深度解析:避免命名冲突与提升代码组织####
本文深入探讨了PHP中命名空间的概念、用途及最佳实践,揭示其在解决全局命名冲突、提高代码可维护性方面的重要性。通过生动实例和详尽分析,本文将帮助开发者有效利用命名空间来优化大型项目结构,确保代码的清晰与高效。 ####
17 1
|
1月前
|
自然语言处理 编译器 Linux
|
17天前
|
编译器 PHP 开发者
PHP 8新特性解析与实战应用####
随着PHP 8的发布,这一经典编程语言迎来了诸多令人瞩目的新特性和性能优化。本文将深入探讨PHP 8中的几个关键新功能,包括命名参数、JIT编译器、新的字符串处理函数以及错误处理改进等。通过实际代码示例,展示如何在现有项目中有效利用这些新特性来提升代码的可读性、维护性和执行效率。无论你是PHP新手还是经验丰富的开发者,本文都将为你提供实用的技术洞察和最佳实践指导。 ####
27 1
|
21天前
|
机器学习/深度学习 存储 人工智能
强化学习与深度强化学习:深入解析与代码实现
本书《强化学习与深度强化学习:深入解析与代码实现》系统地介绍了强化学习的基本概念、经典算法及其在深度学习框架下的应用。从强化学习的基础理论出发,逐步深入到Q学习、SARSA等经典算法,再到DQN、Actor-Critic等深度强化学习方法,结合Python代码示例,帮助读者理解并实践这些先进的算法。书中还探讨了强化学习在无人驾驶、游戏AI等领域的应用及面临的挑战,为读者提供了丰富的理论知识和实战经验。
46 5
|
23天前
|
存储 安全 Java
Java多线程编程中的并发容器:深入解析与实战应用####
在本文中,我们将探讨Java多线程编程中的一个核心话题——并发容器。不同于传统单一线程环境下的数据结构,并发容器专为多线程场景设计,确保数据访问的线程安全性和高效性。我们将从基础概念出发,逐步深入到`java.util.concurrent`包下的核心并发容器实现,如`ConcurrentHashMap`、`CopyOnWriteArrayList`以及`BlockingQueue`等,通过实例代码演示其使用方法,并分析它们背后的设计原理与适用场景。无论你是Java并发编程的初学者还是希望深化理解的开发者,本文都将为你提供有价值的见解与实践指导。 --- ####
|
25天前
|
安全 Java 开发者
AOP中的JDK动态代理与CGLIB动态代理:深度解析与实战模拟
【11月更文挑战第21天】面向切面编程(AOP,Aspect-Oriented Programming)是一种编程范式,它通过将横切关注点(cross-cutting concerns)与业务逻辑分离,以提高代码的可维护性和可重用性。在Java开发中,AOP的实现离不开动态代理技术,其中JDK动态代理和CGLIB动态代理是两种常用的方式。本文将从背景、历史、功能点、业务场景、底层逻辑等多个维度,深度解析这两种代理方式的区别,并通过Java示例进行模拟和比较。
41 4
|
1月前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
116 10

推荐镜像

更多