又或者我们须要剖析不同搜索平台的用户来源剖析,统计不同搜索平台中进入网站的用户个数,根据数据进行精准的勾引和精准的广告投放等:

要想实现上面的受访剖析、来源剖析等业务,必须在实际处理数据的过程中,对用户访问的URL和用户的来源URL进行解析处理,获取用户的访问域名、访问页面、用户数据参数、来源域名、来源路径等信息。

URL的基本组成

在对URL进行解析时,我们要先理解URL的基本组成部分,再根据实际的需求从URL中获取对应的部分,例如一条URL由以下几个部分组成:

jspurlparseURL解析函数及侧视图 Node.js

PROTOCOL:协议类型

通信协议类型,一样平常也叫作Schema,常见的有http、https等;

HOST:域名

一样平常为做事器的域名主机名或ip地址

PATH:访问路径

访问路径目录,由“/”隔开的字符串,表示的是主机上的目录或文件地址

QUERY:参数数据

查询参数,此项为可选项,可以给动态网页通报参数,用“&”隔开,每个参数的名和值用“=”隔开

Hive中的URL解析函数数据准备

Hive中为了实现对URL的解析,专门供应理解析URL的函数parse_url和parse_url_tuple,在show functions中可以看到对应函数

为了更好地学习这两个函数的利用,下面我们在Hive中创建一张表,加载url数据来进行测试。

准备数据

vim /export/data/url.txt

添加以下数据内容

1 http://facebook.com/path/p1.php?query=1

2 http://tongji.baidu.com/news/index.jsp?uuid=frank

3 http://www.jdwz.com/index?source=baidu

4 http://www.itcast.cn/index?source=alibaba

创建数据库

/创建数据库/create database if not exists db_function;/切换数据库/use db_function;

创建表

/创建数据表/create table tb_url(id int,url string) row format delimited fields terminated by '\t';

加载数据

/加载数据/load data local inpath '/export/data/url.txt' into table tb_url;

查看数据

/查询数据/select from tb_url;

需求

基于当前的数据,实现对URL进行剖析,从URL中获取每个ID对应HOST、PATH以及QUERY,终极实现效果如下:

parse_url功能

parse_url函数是Hive中供应的最基本的url解析函数,可以根据指定的参数,从URL解析出对应的参数值进行返回,函数为普通的一对一函数类型。

语法

parse_url(url, partToExtract[, key]) - extracts a part from a URLParts: HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, USERINFO key

parse_url在利用时须要指定两个参数

第一个参数:url:指定要解析的URL

第二个参数:key:指定要解析的内容

示例

SELECT parse_url('http://facebook.com/path/p1.php?query=1', 'HOST') FROM src LIMIT 1;'facebook.com'

SELECT parse_url('http://facebook.com/path/p1.php?query=1', 'QUERY') FROM src LIMIT 1;'query=1'

SELECT parse_url('http://facebook.com/path/p1.php?query=1', 'QUERY', 'query') FROM src LIMIT 1;'1'

测试查询tb_url中每个url的HOST

select id,url,parse_url(url,"HOST") as host from tb_url;

查询tb_url中每个url的PATH

select id,url,parse_url(url,"PATH") as path from tb_url;

查询tb_url中每个url的QUERY

select id,url,parse_url(url,"QUERY") as query from tb_url;

实现需求

selectid,parse_url(url,"HOST") as host,parse_url(url,"PATH") as path,parse_url(url,"QUERY") as queryfromtb_url;

问题

利用parse_url函数每次只能解析一个参数,导致须要经由多个函数调用才能构建多列,开拓角度较为麻烦,实现过程性能也相对较差,须要对同一列做多次打算处理,我们希望能实现调用一次函数,就可以将多个参数进行解析,得到多列结果。

parse_url_tuple功能

parse_url_tuple函数是Hive中供应的基于parse_url的url解析函数,可以通过一次指定多个参数,从URL解析出多个参数的值进行返回多列,函数为分外的一对多函数类型,即常日所说的UDTF函数类型。

语法

parse_url_tuple(url, partname1, partname2, ..., partnameN) - extracts N (N>=1) parts from a URL.It takes a URL and one or multiple partnames, and returns a tuple. All the input parameters and output column types are string.Partname: HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, USERINFO, QUERY:<KEY_NAME>

parse_url在利用时可以指定多个参数

第一个参数:url:指定要解析的URL

第二个参数:key1:指定要解析的内容1

……

第N个参数:keyN:指定要解析的内容N

示例

SELECT b. FROM src LATERAL VIEW parse_url_tuple(fullurl, 'HOST', 'PATH', 'QUERY', 'QUERY:id') b as host, path, query, query_id LIMIT 1;

SELECT parse_url_tuple(a.fullurl, 'HOST', 'PATH', 'QUERY', 'REF', 'PROTOCOL', 'FILE', 'AUTHORITY', 'USERINFO', 'QUERY:k1') as (ho, pa, qu, re, pr, fi, au, us, qk1) from src a;

测试查询tb_url中每个url的HOST、PATH

select parse_url_tuple(url,"HOST","PATH") as (host,path) from tb_url;

查询tb_url中每个url的PROTOCOL、HOST、QUERY

select parse_url_tuple(url,"PROTOCOL","HOST","PATH") as (protocol,host,path) from tb_url;

实现需求

select parse_url_tuple(url,"HOST","PATH","QUERY") as (host,path,query) from tb_url;

问题

当前实现的过程中,通过parse_url_tuple实现了通过调用一个函数,就可以从URL中解析得到多个参数的值,但是当我们将原表的字段放在一起查询时,会涌现以下问题:

select

id,

parse_url_tuple(url,"HOST","PATH","QUERY") as (host,path,query)

from tb_url;

0: jdbc:hive2://node1:10000> select

. . . . . . . . . . . . . .> id,

. . . . . . . . . . . . . .> parse_url_tuple(url,"HOST","PATH","QUERY") as (host,path,query)

. . . . . . . . . . . . . .> from tb_url;

Error: Error while compiling statement: FAILED: SemanticException 3:52 AS clause has an invalid number of aliases. Error encountered near token 'path' (state=42000,code=40000)

UDTF函数的问题

Hive中的一对多的UDTF函数可以实现高效的数据转换,但是也存在着一些利用中的问题,UDTF函数对付很多场景下有利用限定,例如:select时不能包含其他字段、不能嵌套调用、不能与group by等放在一起调用等等。

UDTF函数的调用办法,紧张有以下两种办法:

办法一:直接在select后单独利用

办法二:与Lateral View放在一起利用

Lateral View侧视图功能

Lateral View是一种分外的语法,紧张用于搭配UDTF类型功能的函数一起利用,用于办理UDTF函数的一些查询限定的问题。

侧视图的事理是将UDTF的结果构建成一个类似于视图的表,然后将原表中的每一行和UDTF函数输出的每一行进行连接,天生一张新的虚拟表。
这样就避免了UDTF的利用限定问题。
利用lateral view时也可以对UDTF产生的记录设置字段名称,产生的字段可以用于group by、order by 、limit等语句中,不须要再单独嵌套一层子查询。

一样平常只要利用UDTF,就会固定搭配lateral view利用。

官方链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+LateralView

语法

lateralView: LATERAL VIEW udtf(expression) tableAlias AS columnAlias (',' columnAlias)fromClause: FROM baseTable (lateralView)

基本语法如下

select …… from tabelA lateral view UDTF(xxx) 别名 as col1,col2,col3……

测试单个lateral view调用,实现上述需求中的运用

selecta.id as id,b.host as host,b.path as path,b.query as queryfrom tb_url alateral view parse_url_tuple(url,"HOST","PATH","QUERY") b as host,path,query;

多lateral view调用

selecta.id as id,b.host as host,b.path as path,c.protocol as protocol,c.query as queryfrom tb_url alateral view parse_url_tuple(url,"HOST","PATH") b as host,pathlateral view parse_url_tuple(url,"PROTOCOL","QUERY") c as protocol,query;

Outer Lateral View

如果UDTF不产生数据时,这时侧视图与原表关联的结果将为空,如下图所示:

selectid,url,col1from tb_urllateral view explode(array()) et as col1;

如果加上outer关键字往后,就会保留原表数据,类似于outer join

selectid,url,col1from tb_urllateral view outer explode(array()) et as col1;