Hive 如何 编写 UDAF 函数 解析 电话号码 的归属地以及运营商等字段

创建Hive表

// An highlighted block
CREATE TABLE `chinese`(
  `c1` string,
  `c2` string,
  `c3` string,
  `c4` string)
ROW FORMAT SERDE
  'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
  'field.delim'='\t',
  'serialization.format'='\t')
STORED AS INPUTFORMAT
  'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
  'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'

这里要注意,ORC 、parquet 类型的表要自己测试,Text 文本我这边没啥问题。

导入数据

15801086777 张三 17岁 男
13803457168 李四 57岁 男
17803427561 王五 57岁 女

# 数据用  \t 制表符 分割。
load  data local  inpath   '/root/3.csv' INTO TABLE CHINESE ;
hive> select * from chinese;
OK
	15801086777     张三    17岁    男
	13803457168     李四    57岁    男
	17803427561     王五    67岁    女
Time taken: 0.098 seconds, Fetched: 3 row(s)

查看到数据已经进去了

查看 phone 解析模块

安装模块

使用pip安装:(这里要在每一个节点下安装)

pip install phone

使用:

>>> from phone import Phone
>>> p = Phone()
>>> p.find(1888888)
>>> {'province': '\xe5\x8c\x97\xe4\xba\xac', 'phone_type': '\xe7\xa7\xbb\xe5\x8a\xa8', 
	'city': '\xe5\x8c\x97\xe4\xba\xac', 'area_code': '010', 
	'phone': '1888888', 'zip_code': '100000'}

支持号段
13*,15*,18*,14[5,7],17[0,6,7,8]

改写成 分布式的 map 函数

parse_phone_map.py

# -*- coding: utf-8 -*-
import sys
from phone import Phone

p  = Phone()

for line in sys.stdin:
    phone = line.strip()
    info_dic = p.find(phone)
    #print(info_dic)
    province = info_dic.get('province') or ''
    phone_type = info_dic.get('phone_type') or ''
    city = info_dic.get('city') or ''
    area_code = info_dic.get('area_code') or ''
    phone = info_dic.get('phone') or ''
    zip_code = info_dic.get('zip_code') or ''

    print '\t'.join([province,phone_type,city,area_code,phone,zip_code])

本地测试 map 逻辑

[root@cdh00 hive-python]# cat 1.csv |  awk '{print $1}' | python  parse_phone_map.py
北京    移动    北京    010     15801086777     100000
山西    移动    太原    0351    13803457168     030000
山西    移动    晋城    0356    17803427561     048000

测试结果完全正确

集群上运行

# 添加 python 的 map 文件给 hive。
hive> ADD FILE  /root/tmp/hive-python/parse_phone_map.py;

hive> SELECT TRANSFORM (c1) USING 'python parse_phone_map.py' AS (province, phone_type, city, area_code,phone,zip_code)   FROM chinese ;

###############  结果如下 ################
Total MapReduce CPU Time Spent: 2 seconds 250 msec
OK
北京    移动    北京    010     15801086777     100000
山西    移动    太原    0351    13803457168     030000
山西    移动    晋城    0356    17803427561     048000
Time taken: 23.614 seconds, Fetched: 3 row(s)

# 或者调用 spark 引擎跑更快
hive> set hive.execution.engine=spark;


# 或者是查询出来直接插入到指定有该字段的表当中
hive> INSERT INTO TABLE u_data_new
	  SELECT TRANSFORM (c1) USING 'python parse_phone_map.py'
		 AS (province, phone_type, city, area_code,phone,zip_code) 
	  FROM chinese ;

注意的一些坑

1、本来也想用 java 那套来做,但是本人好久没写 java 了,各种打包,依赖,以及用的第三方的包的源码使用 lombok 注解,导致最后 Hive 查询总是乱码。
2、python 的 phone 模块很久没有 更新了。官网的 phone.dat 数据最新是 2020.04的,建议下载最新的包下来。

电话解析归属地项目链接: link.
phone.dat 数据链接:link

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值