百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

第05章-自定义函数和JSON数据解析

toyiye 2024-07-16 05:54 8 浏览 0 评论

目录


5.1 实现自定义UDF 2

5.2 实现自定义UDTF 3

5.3 实现自定义UDAF 4

5.4 解析JSON数据 6

5.4.1 解析OBJECT数据 6

5.4.2 解析ARRAY数据 7

5.4.3 禁止使用get_json_object函数 8

第05章 自定义函数和JSON数据解析

自定义函数简介

有一些sql很难处理的逻辑,我们可以使用自定义函数去处理。比如对一个字符串加密、对字符串解密、解析json,调用外部服务等。

5.1 实现自定义UDF

UDF就是一进一出的函数,类似于Spark SQL中的round(四舍五入)函数。

输入是一行数据的某一个字段,转为某一个值。

先引入jar包

<dependency>
<groupId>
org.apache.hive</groupId>
<artifactId>
hive-exec</artifactId>
<version>
${hive.version}</version>
<scope>
provided</scope>
</dependency>

再开发UDF代码,我们在这里实现一个将字符串转为大写的功能

/**
* 将字符串转为大写字符串
*/
@Description(name = "up",
value = "_FUNC_(object) - 将字符串转大写字符串")
public class Up extends UDF {
public String evaluate(Object key) {
if(null==key){
return null;
}
return key.toString().toUpperCase();
}
}

再编译代码mvn clean package -DskipTests

并将编译后的代码上传到hdfs上

hadoop fs -put /Users/jack/eclipse-workspace/udf/target/udf-1.0-SNAPSHOT.jar /tmp/hive/

启动spark-sql并创建临时UDF函数

create temporary function up as 'udf.Up' using jar 'hdfs:///tmp/hive/udf-1.0-SNAPSHOT.jar';

使用UDF查询数据

spark-sql> select up("aadbbc");

AADBBC

Time taken: 0.074 seconds, Fetched 1 row(s)

项目github地址:

https://github.com/liukunyuan/udf_new.git

5.2 实现自定义UDTF

UDTF就是一进多出的函数,类似于Spark SQL中的split(对字段分割)函数。将输入的一行数据的某一个字段,转为一个数组。

开发UDTF代码,我们在这里实现一个将字符串转为集合对象的功能

@Description(name = "json_array",
value = "_FUNC_(array_string) - 将字符串转为集合对象")
public class JsonArray extends UDF {
public ArrayList<String> evaluate(String jsonString) throws JSONException {
if (StringUtils.isBlank(jsonString)) {
return null;
}
JSONArray extractObject =
new JSONArray(jsonString);
ArrayList<String> result = new ArrayList<String>();
for
(int i = 0; i < extractObject.length(); i++) {
result.add(extractObject.get(i).toString())
;
}
return result;
}
}

再编译代码mvn clean package -DskipTests

并将编译后的代码上传到hdfs上

hadoop fs -put /Users/jack/eclipse-workspace/udf/target/udf-1.0-SNAPSHOT.jar /tmp/hive/

启动spark-sql并创建临时UDTF函数

create temporary function json_array as 'udtf.JsonArray' using jar 'hdfs:///tmp/hive/udf-1.0-SNAPSHOT.jar';

使用UDTF查询JSON数据

spark-sql> select json_array("[{ \"name\": \"XiaoHong\", \"age\":18}]");

["{"name":"XiaoHong","age":18}"]

Time taken: 0.055 seconds, Fetched 1 row(s)

spark-sql>

5.3 实现自定义UDAF

UDAF就是多进一出的函数,类似于Spark SQL中的count(求条数)函数。将输入的多行数据的某一个值,转为一个值。

开发UDAF代码,我们在这里实现一个求平均数的功能。

参考:org.apache.hadoop.hive.contrib.udaf.example.UDAFExampleAvg



@Description(name = "avg_num",
value = "_FUNC_(col) - 计算平均数")
public class AvgNum extends UDAF {
public static class UDAFAvgState {
private long mCount;
private double
mSum;
}
public static class UDAFExampleAvgEvaluator implements UDAFEvaluator {
UDAFAvgState
state;
public
UDAFExampleAvgEvaluator() {
super();
state = new UDAFAvgState();
init();
}
public void init() {
state.mSum = 0;
state.mCount = 0;
}
/**
* 遍历所有行
*
@param o
* @return
*/
public boolean iterate(Double o) {
if (o != null) {
state.mSum += o;
state.mCount++;
}
return true;
}
/**
* 输出部分聚合结果
*
@return
*/
public UDAFAvgState terminatePartial() {
// This is SQL standard - average of zero items should be null.
return state.mCount == 0 ? null : state;
}
/**
* 提前合并部分数据
*
@param o
* @return
*/
public boolean merge(UDAFAvgState o) {
if (o != null) {
state.mSum += o.mSum;
state.mCount += o.mCount;
}
return true;
}
/**
* 终止聚合并返回最终结果
*
@return
*/
public Double terminate() {
// This is SQL standard - average of zero items should be null.
return state.mCount == 0 ? null : Double.valueOf(state.mSum
/ state.mCount);
}
}
}

再编译代码mvn clean package -DskipTests

并将编译后的代码上传到hdfs上

hadoop fs -put /Users/jack/eclipse-workspace/udf/target/udf-1.0-SNAPSHOT.jar /tmp/hive/

hadoop fs -put /Users/jack/Desktop/test.csv hdfs:///tmp/hive/csv/

启动spark-sql并创建临时UDAF函数

create table default.csv(data int)

location '/tmp/hive/csv';

create temporary function avg_num as 'udaf.AvgNum' using jar 'hdfs:///tmp/hive/udf-1.0-SNAPSHOT.jar';

使用UDAF查询数据

spark-sql> select avg_num(data) ,avg(data) from default.csv;

93.4 93.4

Time taken: 1.888 seconds, Fetched 1 row(s)

可以发现,我们实现的求平均数和引擎自带的avg功能一致。

5.4 解析JSON数据

在大数据处理中,我们经常会遇到一些json格式的数据,所以我们必须掌握如何在Spark SQL中处理json数据。而json数据分为json object格式和json array格式。而我们将通过如下学习掌握这2种json格式数据的通用解析方法。

5.4.1 解析OBJECT数据

通过lateral view outer json_tuple解析json object类型数据,单次可以解析多个key,性能比get_json_object好。

创建存放json数据的目录

hadoop fs -mkdir hdfs:///tmp/hive/json

将JSON数据上传到hdfs

hadoop fs -put /Users/jack/Desktop/test.json hdfs:///tmp/hive/json/

create table default.test (data string)

location '/tmp/hive/json';

书写sql查询数据里面的所有class

select t2.class

from default.test t

lateral view outer json_tuple(data,'class','cmd') t2 as class,cmd

limit 10;

注意:不要使用get_json_object处理json object数据,如果解析多个字段,会重复解析多次,性能很差。

5.4.2 解析ARRAY数据

通过我们前面编写的自定义函数json_array将字符串转成array类型数据,然后通过LATERAL view explode将array进行行转列。通过这种方式解析json array数据。

书写sql查询第二层的class字段

select t4.cmd_class

from default.test t

lateral view outer json_tuple(data,'class','cmd') t2 as class,cmd

LATERAL view explode(json_array(cmd)) t3 as tmp_object

lateral view outer json_tuple(tmp_object,'class') t4 as cmd_class

limit 10;

5.4.3 禁止使用get_json_object函数

这是我们优化json解析的生产案例:

优化前,解析json需要执行360分钟。优化后,解析json只需要执行24分钟,性能优化了15倍。

这是优化前的sql,有1000个get_json_object解析

select

t1.biz_no,

from_unixtime(cast(t1.date_created/1000 as int),'yyyy-MM-dd') as date_created,

get_json_object(t1.req_data,'$.hfwCredit_cust.casesNum') casesNum,

get_json_object(t1.req_data,'$.hfwCredit_cust.breakFaithNum') breakFaithNum,

get_json_object(t1.req_data,'$.caseInfo.custNo') cust_no,

get_json_object(t1.req_data,'$.caseInfo.adjDate') adjDate

……………………

from hdp_credit.xx t1 where pday='${pday}';

这是优化后的sql,使用lateral view outer json_tuple进行json解析。

select biz_no, pday, date_created, casesNum, breakFaithNum, adjDate, custNo

from (

select t1.biz_no,

pday,

from_unixtime(cast(t1.date_created / 1000 as int), 'yyyy-MM-dd') as date_created, map_array(t1.resp_data, 'dcItem,dcVal') as resp_data_json,

t2.*

t3.*

t4.*

from

(select * from hdp_credit.xx

where pday='20220424' ) t1

lateral view outer json_tuple(t1.req_data,'caseInfo','hfwCredit_cust') t2 as caseInfo,hfwCredit_cust

lateral view outer json_tuple(hfwCredit_cust,'breakFaithNum','casesNum') t3 asbreakFaithNum,casesNum lateral view outer json_tuple(caseInfo,'adjDate','custNo') t4 as adjDate,custNo

)tt

;


来自视频:《Spark SQL性能优化》

链接地址:

https://edu.51cto.com/course/34516.html

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码