GMV(一定时间内的成交总额)是一个衡量电商网站营业收入的一项重要指标,例如淘宝,京东都有这样的衡量标准,感兴趣的朋友可以自己科普下这方面的概念知识。
当然散仙今天,并不是来解释概念的,而是记录下最近工作的一些东西,原来我们平台的GMV只有一个总的成交金额,并没有细分到各个系统的GMV的比重,比如搜索端,推荐端,移动端等等。
通过细粒度的分析各个系统所占的比重,对于指导各个系统完善和发展有一定的重要意义,这里不就深说了,下面先来看下散仙分析的搜索gmv的数据布局方式。
(1)Hadoop集群上,存储了一些非核心的数据,比如访问数据,点击数据,购物车数据,下单数据(这个是从数据库里每天同步到HDFS上的,算是备份吧)
(2)Oracle数据库中,存储了订单信息,交易信息,商品信息,支付信息等一些电商的核心数据
其实关于gmv的计算方式,在我们oracle库里,以及有一个存储过程封装了复杂的细节的处理,包括运费,折扣,不同国家,不同地域,信用用户,等等,在使用时候,只需要传入一个订单编号即可,计算出本单的gmv成交金额。
这样以来的,按照目前的数据情况,订单编号是从Hadoop集群上,一直是从搜索,点击,添加购物车,下单计算出来的,然后获取的对应的订单编号,注意这个过程中,是需要全程去爬虫数据的,因为还要算最终的GMV成交额,所以需要找到一定时期内的订单号,然后通过调用在oracle库的封装好的函数,计算出gmv,这样以来,就能够比较细跟踪各个阶段运行轨迹和成交额。
ok,业务上的分析大致如此,下面就看下,技术上如何实现,其实就是需要Pig的一个自定义UDF函数,在遍历每一行的recoder时,去查询oracle只读库,获取gmv的值,并将最终结果存储起来,以图形化方式展示。
Pig里面对UDF函数非常丰富,比较常用的是转化函数和加载存储函数,这一点在Hive里,也是如此,之前的文章中,散仙介绍过,通过自定义UDF将pig分析的结果直接存储到数据库或索引中,便于检索和发挥不同框架之间的组合优势。
核心代码如下:
package com.pig.dhgate.getgvmbyrfxno;
import java.io.IOException;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 自定义Pig UDF实现查询db计算gmv
* **/
public class GetGmvByRfxno extends EvalFunc<Double> {
/**日志对象*/
static Logger log =LoggerFactory.getLogger(GetGmvByRfxno.class);
/**数据库工具类*/
DBTools dbtools=new DBTools();
@Override
public Double exec(Tuple input) throws IOException {
if(input!=null&&input.size()!=0){
//获取传入的订单号
String rfxno =(String)input.get(0);
//通过db类,查询对应的gmv并返回
double gmv=dbtools.getGmvByRfxno(rfxno);
return gmv;
}else{
//对null,空值,一律按0处理
return 0.00;
}
}
}
数据库封装类:
/***
* 数据库工具类
* */
public class DBTools {
/**日志对象*/
static Logger log =LoggerFactory.getLogger(DBTools.class);
private static Connection conn;
private static PreparedStatement ps;
private ResultSet rs;
//从虚拟表查询函数
private static String sql="select datasql.GETGMV(?) as gmv from dual ";
static{
try{
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@ip地址:1521:数据库名", "用户名", "密码");
System.out.println("数据库连接:"+conn);
ps=conn.prepareStatement(sql);
}catch(Exception e){
log.error("初始化oracle驱动异常!", e);
}
}
/**根据一个rfxno获取对应的产品的gmv
* **/
public double getGmvByRfxno(String rfxno){
try{
ps.setString(1, rfxno);
rs = ps.executeQuery();
if(rs.next()){
double gmv=rs.getDouble("gmv");
// System.out.println("gmv是: "+gmv);
return gmv;
}
rs.close();
}catch(Exception e){
log.error("根据rfxno获取gmv出错!",e);
}
return 0.0;
}
}
其实,代码还是比较简单的,在这里,你可以从任何数据源获取需要的数据,而不仅仅是数据库,你也可以从redis,memcache,文件,xml,等等里获取需要组合用的数据。
遇到一个异常:在sql语句后面,不用加分号,类似下面的这样的语句,通过jdbc编译然后调用oracle是不通过的:
select datasql.GETGMV(?) as gmv from dual;
这一点需要注意下。
最后来看下如下在pig脚本里,使用自定义的函数:
(1)使用ant打包自定义的udf函数的jar
(2)在pig脚本里,注册相关的jar包,注意如果有依赖关系,依赖的jar包,也需要注册,例如本例中的oracle的jdbc的驱动包
(3)在对应的地方,通过类的全路径名,引用此函数,完成对应的查询转换,并将新得到的一个字段,作为原始一行记录的字段扩充。
脚本如下:
--注册依赖的jar包
register /home/search/dongliang/nsconvent/checklist/ojdbc.jar
register /home/search/dongliang/nsconvent/checklist/tools.jar
--加载原有数据
m = load '/tmp/mdm/VW_TD_RFX' using PigStorage('\\x07');
--加载原有数据
n = load '/tmp/mdm/TD_RFX_PRODUCT' using PigStorage('\\x07');
--过滤出符合时间的数据
m= filter m by ToMilliSeconds(ToDate($3,'yyyy-MM-dd HH:mm:ss')) >= ToMilliSeconds(ToDate('$day 00:00:00','yyyy-MM-dd HH:mm:ss')) and ToMilliSeconds(ToDate($3
,'yyyy-MM-dd HH:mm:ss')) <= ToMilliSeconds(ToDate('$day 23:59:59','yyyy-MM-dd HH:mm:ss')) ;
--提取相关字段,并完成计算
m = foreach m generate $0 as arfid, $1 as rfxno , com.pig.dhgate.getgvmbyrfxno.GetGmvByRfxno((chararray)$1) as gmv , $4 as bid ;
--获取topN数据
m = limit m 10 ;
--打印输出
dump m;
想了解更多有关电商互联网公司的搜索技术和大数据技术的使用,请欢迎扫码关注微信公众号:我是攻城师(woshigcs)
本公众号的内容是有关搜索和大数据技术和互联网等方面内容的分享,也是一个温馨的技术互动交流的小家园,有什么问题随时都可以留言,欢迎大家来访!
分享到:
相关推荐
apache pig 基础及应用,urldecode row_number web日志分析 根据 用户行为 做出 简易的 相似度 判断。
pig官方的udf教程,介绍了 Writing Java UDFs Writing Python UDFs Writing JavaScript UDFs Writing Ruby UDFs Piggy Bank,一个开源pig的udf包,主要是java
udf函数,用户自定义函数,可以直接在sql语句中计算的函数 优点: 允许实现模块化的程序设计、方便修改代码、增加函数 UDF的执行速度很快,通过缓存计划在语句重复执行时降低代码的编译开销,比存储方法的执行效率...
hive的udf函数实现
由于impala处理日期的函数如date_sub(),date_trunc(),last_day()等这些日期处理函数还需要进行日期格式化为yyyy-MM-dd使用,sql代码段过长,导致频繁嵌套过于复杂.所以自定义udf函数解决这些问题.以下为实现过程.
1.从HDFS中加载数据到DataFrame中 2.注册UDF函数,函数名为toUpper就是将所有名字变成大写 3.创建临时视图,然后执行注册的函数
pig udf,实现了 urldecode、 row_number、 tomap.版本使用cdh4.1.2,如果需要在别的版本中使用,请替换工程文件中的两个jar包,对应您需要的版本。
pig udf 示例
大数据运维 郭现伟 大数据之运维全文共12页,当前为第1页。 大数据知识图谱 大数据之运维全文共12页,当前为第2页。 大数据运维知识图谱 大数据之运维全文共12页,当前为第3页。 Hadoop简介 Hadoop是一个能够让用户...
主要介绍了大数据 java hive udf函数(手机号码脱敏),的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
fluent中的UDF中文教程,比较有用的
fluent多相流DPM模型中使用用户自定义函数对颗粒进行统计
PigIp工具关于这是一组Apache Pig Java UDF实用程序,可使用, , , 和其他,帮助我们提高生产效率。执照 。快速开始这基本上是如何使用库的所有IP功能的示例 -- Register PigIpTools library ...
phoenix-udf自定义函数,上传到hdfs的lib目录,测试udf自定义函数功能,有需要可以下载;select QUARTER(birth) from person
FromJsonInferSchema :包装 JsonLoader 以将字符数组(字符串)字段中的 JSON 转换为 Map 的 Pig UDF。 推断输出的模式。 FromJsonWithSchema :与 FromJsonInferSchema 类似,但您提供架构。 这些工具适用于 ...
Used in Fluent
oink 是基于 REST 接口,用于 Apache Pig 执行。Oink 是基于 Servlet 的 Pig ,提供以下功能:注册/注销/查看 Pig 脚本注册/注销/查看 jar 文件 (用于自定义 UDF 函数)执行 Pig 工作查看 Pig 工作的数据/状态取消...
该文档详细描述了Maxcompute函数的两种UDF函数注册方式,以及多个jar包如何打包成一个jar包的方式。
Fluent软件入口边界自定义udf,用于边界条件自定义。
简要的介绍用户自定义函数UDF及其在FLUENT中的用法,主要包括什么是UDF、威为什么使用UDF、UDF的局限、UDF基础、解释和编译UDF等