2、用Kettle生成日期维度数据(一)使用kettle生成2019年日期文件保存到hive表中
程序员文章站
2024-02-13 23:12:58
...
记录5月4号导入数据的过程,以便以后更方便使用这个方法
1、需求:
为了后续分析销售订单金额、订单笔数的周环比、周同比、月环比、月同比,需要提前使用Kettle生成时间维度
工具(环比是相邻比较,同比是历史同期比较)
按照以下字段生成 2019年一年的日期维度数据
分析:
日期使用 Canlendar、SimpleDateFormat,编写Javascript脚本实现
国家法定节假日实现,需要往http://api.goseek.cn/Tools/holiday?date=20190102 年月日,发送请求,获取结
果,以下为该REST API接口简介
1、接口地址:http://api.goseek.cn/Tools/holiday?date=数字日期,支持https协议。
2、返回数据:正常工作日对应结果为 0,,休息日对应结果为 1, 法定节假日对应结果为 2
3、节假日数据说明:本接口包含2017年起的中国法定节假日数据,数据来源国务院发布的公告,每年更新1次,确保数据 最新
4、示例:
http://timor.tech/api/holiday/info/2018-03-02
返回数据:
{"code":0,"type":{"type":0,"name":"周五","week":5},"holiday":null}
{
"code": 0, // 0服务正常。-1服务出错
"type": {
"type": enum(0, 1, 2,3), // 节假日类型,分别表示 工作日、周末、节日、调休。
"name": "周六", // 节假日类型中文名,可能值为 周一 至 周日、假期的名字、某某调休。
"week": enum(1 - 7) // 一周中的第几天。值为 1 - 7,分别表示 周一 至 周日。 },
"holiday": {
"holiday": false, // true表示是节假日,false表示是调休
"name": "国庆前调休", // 节假日的中文名。如果是调休,则是调休的中文名,例如'国庆前调休'
"wage": 1, // 薪资倍数,1表示是1倍工资
"after": false, // 只在调休下有该字段。true表示放完假后调休,false表示先调休再放假
"target": '国庆节' // 只在调休下有该字段。表示调休的节假日 } }
2、需要生成的字段
date_key、date_value、day_in_year、day_in_month、is_first_day_in_month、
is_last_day_in_month、weekday、week_in_month、is_first_day_in_week、is_dayoff、
is_workday、is_holiday、date_type、month_number、year、
quarter_name、quarter_number 、year_quarter string、year_month_number
使用Kettle构建以下组件结构图
生成记录
增加序列
Javascript代码
Http Client组件
JSON Input
Switch/case
字段映射为常量
工作日
法定节假日
节假日调休补班
休息日
字段选择
parquet Output
流程图:
注意:Http Client组件(5个并行度)是设置完一个然后复制粘贴连接多个,为了提高效率
生成记录
增加序列:
JavaScript代码
//Script here
// 生成2000-01-01的日期和2000-01-02的日期数据
// 2000-01-02的需要是2000-01-01 +1 成的
// 初始化数据是2000-01-01
var initData="2019-01-01";
// 变量N 天
// 设置日期的格式
var formatter = java.text.SimpleDateFormat("yyyy-MM-dd");
// 将string日期转为date
var date = formatter.parse(initData);
// 创建一个日历对象
var calendar=java.util.Calendar.getInstance();
calendar.setTime(date);
// 设置日历的初始值
// 获取代理健
formatter.applyPattern("yyyyMMdd");
var date_key = formatter.format(calendar.getTime());
// 原始值+1
formatter.applyPattern("yyyy-MM-dd");
calendar.add(java.util.Calendar.DAY_OF_MONTH,liner);
// 1、获取日期年月日
var date_value = formatter.format(calendar.getTime());
// 2、获取一年中的第几天
var day_in_year = calendar.get(java.util.Calendar.DAY_OF_YEAR)+"";
// 获取当月中的第几天
var day_in_month = calendar.get(java.util.Calendar.DAY_OF_MONTH)+"";
// 是否是月的第一天
var is_first_day_in_month ="n";
var i1 = calendar.get(java.util.Calendar.DAY_OF_MONTH);
if(i1==1){
is_first_day_in_month="y";
}
// 是否是月的最后一天
var is_last_day_in_month = "n";
calendar.add(java.util.Calendar.DAY_OF_MONTH,1);
var i2 = calendar.get(java.util.Calendar.DAY_OF_MONTH);
if(i2==1){
is_first_day_in_month="y";
}
// 把日期变回去
calendar.add(java.util.Calendar.DAY_OF_MONTH,-1);
// 星期几 减去一才是正确的周几
var weekday = (calendar.get(java.util.Calendar.DAY_OF_WEEK) -1)+"";
// 判断当为-1为0的时候转为7
if(weekday.equals("0")){
weekday="7";
}
// 月的第几个星期
formatter.applyPattern("w");
var week_in_month = formatter.format(date);
// 是否周一
var is_first_day_in_week="n";
if( weekday.equals("1")){
is_first_day_in_month="y";
}
// 2.10 是否休息日
var is_dayoff = "n";
// 2.11 是否工作日
var is_workday = "n";
// 2.12 是否国家法定节假日
var is_holiday = "n";
// 2.12 国家法定节假日获取URL
var holiday_url = "http://wow.kamisamak.com/api.php?date="+date_value
// 2.13 日期类型
var date_type = "workday";
// 月份
formatter.applyPattern("MM");
var month_number = formatter.format(date);
// 年份
formatter.applyPattern("yyyy");
var year = formatter.format(date);
// 季度名称、季度、年季度
var quarter_name="";
var quarter_number="";
var year_quarter="";
switch (calendar.get(java.util.Calendar.MONDAY)){
case java.util.Calendar.FEBRUARY:
case java.util.Calendar.JANUARY:
case java.util.Calendar.MARCH:
quarter_name="Q1";
quarter_number="1";
year_quarter=year+"-"+quarter_name;
break;
case java.util.Calendar.APRIL:
case java.util.Calendar.MAY:
case java.util.Calendar.JUNE:
quarter_name="Q2";
quarter_number="2";
year_quarter=year+"-"+quarter_name;
break;
case java.util.Calendar.JULY:
case java.util.Calendar.AUGUST:
case java.util.Calendar.SEPTEMBER:
quarter_name="Q3";
quarter_number="3";
year_quarter=year+"-"+quarter_name;
break;
default:
quarter_name="Q4";
quarter_number="4";
year_quarter=year+"-"+quarter_name;
break;
}
// 年_月份
formatter.applyPattern("yyyy-MM");
var year_month_number=formatter.format(date);
javascriprt字段
http client设置
设置好之后拷贝几个一样的连接,增加处理holiday url字段的效率
json input
$.[0].info获取前面网址返回的json里返回的字符串
Switch / case
(这里的Datetype返回的值是字符串对应case值)
工作日
周末
节假日
字段选择
文本输出:
指定分隔符为逗号
在hive中创建一个表,表的字段顺序对应生成文本的字段
建表语句
CREATE TABLE `date2019`
(
`date_key` string comment "代理键 (年月日)",
`date_value` string comment "年-月-日",
`day_in_year` string comment "当年的第几天",
`day_in_month` string comment "当月的第几天",
`is_first_day_in_month` string comment "是否月的第一天",
`is_last_day_in_month` string comment "是否月的最后一天",
`weekday` string comment "星期",
`week_in_month` string comment "月的第几个星期",
`is_first_day_in_week` string comment "是否周一",
`year` string comment "年份",
`quarter_name` string comment "季度",
`quarter_number` string comment "年-季度",
`year_quarter` string comment "年-月份",
`year_month_number` string comment "季度名称",
`is_dayoff` string comment "是否休息日",
`is_workday` string comment "是否工作日",
`is_holiday` string comment "是否国家法定节假日",
`date_type` string comment "日期类型: 节假日/工作日/周末",
`month_number` string comment "月份"
) row format delimited fields terminated by ',' stored as TEXTFILE;
//把生成的文本文件上传到linux上,在hive把本地数据传到表中
load data local inpath '/video/aaa/项目准备.txt' into table date2019;