数据产品通用复合指标查询计算的实践
本文由作者王改革授权网易云社区发布。
一、背景和实现目标
在开发严选数据产品(大麦商品数据运营平台和移动数据工作台VIPAPP)的时候,最多的业务场景就是对实时和离线数据模型中查询、处理、统一数据结构返回给前端。所以在开发的同时也一直在思考如何将这些相似的数据处理流程统一起来,更关注数据指标本身。
开发中经常遇到的几个问题是:
数据查询连接管理分散
模型查询结果缓存分散
对于模型数据查询结果缺少统一的数据变换模块支持,每日产出的实时数据指标以及离线数据指标经过后端逻辑做接口返回的时候,会有大量的get、set操作,如果同时需要计算指标同比、环比、占比、对比值等复合指标时,就会充斥大量的重复脏代码。
依赖的数据服务对存储在MySQL、GP、Kylin、HBase等存储引擎的数据模型暂时没有多模型的连接支持。
所以针对以上问题,我们希望能够设计出能够在数据产品中使用的通用指标查询计算模块(DPRequestManager),主要实现如下目标:
管理数据模型查询,封装对于 统一查询服务(DQS)、MySQL等查询请求,提供查询连接池。
提供灵活的数据变换能力
能够通过配置对相应指标(包括指标值、环比、占比、同比等)自动计算,减少过多的冗余代码。
支持数据对象映射,减少频繁的取值和赋值操作
支持查询级别的缓存(可以根据系统需求自定义缓存时间、可以设定缓存条件),减少对依赖服务的查询压力。
二、通用指标查询计算模块(DPRequestManager)组织结构
红色部分的并发查询器负责管理数据产品与底层数据查询存储引擎的连接,统一管理各种数据查询。DPRequestManager会作为数据产品模型查询的统一入口,封装底层数据模型存储引擎,为数据查询提供线程池服务。同时此部分还提供模型退化的能力。
统一缓存模块负责对数据查询做条件缓存,对于每日数据未产出或者其他情况可以对查询结果约定一些必要条件来决定是否缓存查询结果(缓存级别为请求级别)。
橙色部分的数据变换模块可以对DQS获取的多表数据进行灵活数据变换
配置模块可以对数据关系映射以及相应的复合指标计算做相应配置,统一生成结果,减少冗余代码
三、数据变换模块支持操作
对于从模型存储引擎查询结果处理成List<Map<String, Object>>结构的,并提供提供以下数据变换操作。
命名规则:模块内部将使用数据dataKey存放查询处理结果,dateKey对应的list结果可以类比excel行列表,其中的列名对应Map结构的key值。
现在主要提供如下数据操作:
- compose(多个查询集合进行组合,做内存连接使用,对于多个数据中存在同名列的情况,可选择按照FIFO进行是否覆盖)
compose({"group_id", "group_name"}, "result_A", "resultB")
- rename(将数据某一列列名重新命名)group(基于元数据行进行分组)
rename ("dk", {"sale_amount_day", "sale_qty_day"}, {"sale_amount, sale_qty"})
- group(基于数据行进行分组)
group(row -> new StringJoiner("_").add(row.get("week").add(row.get("group_id")))
- aggregation(基于数据行进行分组, 然后对度量指标字段进行聚合)
aggregation({"week", "group_id", "group_name"}, {sum("sale_amount"), sum("sale_qty")})
- shape(数据变形,将多列数据变成宽表数据,平坦化透视表结构)
- intersection(多个数据集合取交集)
- top(根据有序度量取top集合)
四、指标计算配置以及对象关系映射
这个地方主要解决两个问题:
模型数据查询结果到数据对象的映射,减少频繁的取值和赋值,现在通用的ORM框架都能解决这个问题,DPRequestManager为了配合复合指标计算通过反射来实现数据对象映射部分。
映射过程中的指标计算(指标表达式计算、环比、同比、占比等复合指标的计算)
DPRequestManager主要是通过两个配置来配合解决复合指标计算的问题。
第一个配置主要是定义数据对象映射的数据筛选规则(目标数据集合、环比数据集合、占比数据集合等)
{
"clazz": StockDTO.class,
"useDate": "2018-12-07", // 指定目标值日期
"hbDate": "2018-12-06", // 指定环比日期
"hbKey": "group_id", // 计算环比使用
"filterKey": "", // 过滤器
"filterValue": ""
}
第二个配置是数据对象DTO的配置(通过注解对复合指标计算进行配置定义)
DTO配置主要使用了三个注解,@FromDO,@FunctionDO,@IgnoreAssign
@From 定义简单按key取值
@FunctionDO定义复合指标计算规则(hb,tb,zb,avg,sum等)
@IgnoreAssign 对象映射是字段忽略
同时支持定义的复合指标对象的指标计算赋值。
@Datapublic class StockSingleVO extends BaseVO { // 简单取值,默认驼峰转下划线取字段group_id
private Long groupId; @FromDO("'商品组:'+group_name") private String groupName; // 简单取值,直接在库量
@FromDO("stock_cnt_zhuzhan_1d") private Number stockCnt; // 环比,对在库量字段计算环比
@FromDO("stock_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.HB) private Number stockCntHB; // 简单取值,计算在库+在途量
@FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") private Number stockAndOnwayCnt; // 环比计算,计算在库+在途的环比
@FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.HB) private Number stockAndOnwayCntHB; // 占比计算
@FromDO(value = "stock_cnt_zhuzhan_1d+onway_cnt_zhuzhan_1d") @FunctionDO(types = FunctionTypeEnum.ZB) private Number stockAndOnwayCntZB;
}
数据过滤规则配置和数据对象中定义的复合指标计算配置一起支持数据对象映射,这样可以减少大量重复赋值取值以及手动计算复合指标的工作。同时配合使用数据变换模块和数据对象映射能够释放更大的灵活性,将数据变换模块、数据对象映射、复合指标计算模块解耦。
模块查询代码示例:
/**
- condition1,condition2为构造的指标查询条件
*/EngineRequest request1 = new EngineRequest(EngineType.DQS, condition1, EngineResultTypeEnum.LIST); // 构造查询请求1EngineRequest request2 = new EngineRequest(EngineType.DQS, condition2, EngineResultTypeEnum.LIST); // 构造查询请求2// 构造配置1(数据过滤配置 -> 配置目标日期、环比日期、计算环比目标分组key)EngineConvertConfig config = new EngineConvertConfig<>(StockSingleVO.class, "2018-12-07", "group_id", null, null);
config.setHbDate("2018-12-06");
Listlist = requestEngineManager.initThreadLocal()
.addRequest(dk1, request1).addRequest(dk2, request2).execute().compose(true, Arrays.asList("date_id", "group_id"), dk_new, dk1, dk2) // 请求结果连接.converToList(dk_new, config); // 数据对象映射// 前端数据结构组装SmartQueryResult result = BaseVO.assembleResult(list, StockSingleVO.class);
五、总结
数据产品中很多通用的部分可以抽出来作为单独模块或者服务。文中介绍的复合指标查询模块已经在大麦商品数据运营平台中实践,它把数据产品指标查询、计算以及对象映射等公共部分提取出来,有效的提高开发效率并能够降低开发成本。
文章来源: 网易云社区
数据产品通用复合指标查询计算的实践相关推荐
- 1.产品/数据产品设计
1. 概述 产品设计逻辑和流程可以分为3个环节:用户需求调研梳理.产品设计流程和产品原型及需求文档 数据产品的本质是更好地为用户提供信息服务.数据产品设计的关键点和起点在于深刻准确地把握用户需求,而用 ...
- 数据圈最全的数据产品文章全集
大家好!今天给大家一个我的老朋友:「一个数据人的自留地」,数据人自留地是一个集数据产品.数据分析.数据仓库.产品策略与一体的数据人专属社群.创始人大鹏老师,拥有8年的数据经验,现在是人人都是产品经理专 ...
- GEDI学习笔记1:数据产品简介
GEDI 科学数据产品包括描述地球 3D 特征的足迹和网格数据集.这些数据产品被分配了不同的级别,这表明了数据在收集后所经历的处理量.所有产品都是公开可用的,其中较低级别的产品(L1 和 L2)来自 ...
- 【限时干货】数据圈火爆的数据产品文章全集
关注公众号,回复"进群",与3万+数据人交流 公众号介绍 @一个数据人的自留地 成立于2020年2月25日. 目前发表原创400+篇,拥有4万+粉丝,交流群10+个. 连载数据产品 ...
- 数据产品设计的3个方法论
写这篇小文主要是因为这几年总是阴错阳差地与数据打着不大不小的交道,也是想总结一下自己对数据产品的一些思考和认识,看看自己是否真的适合在这条路上一直走下去. 何谓数据产品 按照惯例,第一次听说数据产品这 ...
- 华为云大数据存储的冗余方式是三副本_阿里云大数据产品 | 大数据计算
阿里云大数据计算产品包括MaxCompute.E-MapReduce和实时计算(Alibaba Cloud Realtime Compute). 一.MaxCompute 1.MaxCompute概述 ...
- 数据产品--浅析如何搭建维度指标系统
浅析:将数据进行可视化.工具化,根据市场和产品需求进行指标体系设计.计划围绕这个点,描述自己对数据产品设计的一些感受,本文将持续完善. 我们的最终目标:数据驱动增长,个人理解所有繁杂的系统背后目的其实 ...
- 数据产品-数据指标标签常用sql函数
SQL能力是作为数据产品经理必不可少的技能,当然,作为数据产品,我们对SQL的查询效率的要求可能不像开发那么高.而对于SQL的学习一般也是只需懂DQL查询语言就行,对于DCL.DDL.DML这些一般只 ...
- 数据产品-指标标签体系构建
作为刚毕业不到一年的数据产品经理,今天和大家分享一下我接触到和认知范围内的数据产品经理关于数据指标标签体系的构建过程是什么样子的 1.解读数据库数据 ①在我们公司(家居互联网行业),我们作为数据部门, ...
最新文章
- 机器大神 Michael Jordan 教授主题演讲:机器学习——创新视角,直面挑战》
- 4、MySQL设置事务自动提交(开启和关闭)
- [文章备份]源代码制图工具Understand最新可用注册码
- F盘无法访问设备硬件出现致命错误,导致请求失败数据找回的方案
- 聊一聊单机、集中式、分布式和云原生存储
- mysql 免安装 配置_图解MySQL5.7.20免安装版配置方法
- Linux下查看文件和文件夹大小的df和du命令(链接)
- go语言学习路线图_开篇:Go 语言的优势与学习路线图
- PAT甲题题解-1077. Kuchiguse (20)-找相同后缀
- HashSet和HashMap的区别 1
- php 计算两点地理坐标的距离
- php删除与销毁session
- Win7连接蓝牙4.0鼠标
- 如何查看python标准库_python标准库
- 圣经中真的藏有密码吗?
- 小牛电动IPO:四年跌宕起伏 一代天才少年李一男终圆梦
- 本地存储-系统和保留-系统文件占用存储空间过大的解决方式
- python 回溯法 01背包问题_Python基于回溯法解决01背包问题实例
- word中设置页眉页脚奇偶页不同,页脚为页码时偶数页不显示一招解决
- 春天来了,该播种了。久久荒芜的博客重新耕种起来
热门文章
- 全球及中国枕式自动包装机行业需求现状与投资机会评估报告2022-2027年版
- 好品山东谋定产业扶贫-农业大健康·万祥军:乡村振兴行动
- 世界人民盼丰收-国际农民丰收节贸易会:世界农民节日
- openresty开发系列27--openresty中封装redis操作
- 每日Linux命令(1)-date
- H5案例分享:移动端滑屏 touch事件
- 4、3ds Max 的基本模型和操作 之 3ds Max 的对象操作
- Android学习笔记--JNI的使用方法
- Eclipse中启动tomcat报错:A child container failed during start
- 移动端界面中的版式设计原理