【实时数仓】DWS层之关键词主题表(FlinkSQL)、数据可视化接口、Sugar数据大屏、总成交金额接口实现

一 DWS层-关键词主题表(FlinkSQL)

1 过滤数据

// TODO 4 将动态表中表示搜索行为的记录过滤出来
Table fullwordTable = tableEnv.sqlQuery("select " +
        "  page['item'] fullword,rowtime " +
        " from " +
        "  page_view " +
        " where " +
        "  page['page_id']='good_list' and page['item'] is not null");

2 利用UDTF进行拆分

(1)拆分结果

搜索内容:荣耀Play6T Pro 天玑810
	fullword				rowtime
荣耀Play6T Pro 天玑810		20221215

拆分后的效果:荣耀  Play6T  Pro  天玑  810
     keyword		   rowtime
	  荣耀			20221215
	  Play6T		  20221215
	  Pro			  20221215
	  天玑			20221215
	  810  		      20221215

(2)Join 表函数 (UDTF)

将表与表函数的结果进行 join 操作。左表(outer)中的每一行将会与调用表函数所产生的所有结果中相关联行进行 join 。

用户自定义表函数( User-defined table functions,UDTFs ) 在执行前必须先注册。请参考 UDF 文档 以获取更多关于指定和注册UDF的信息

(3)代码

// TODO 2 注册自定义UDTF函数
tableEnv.createTemporarySystemFunction("ik_analyze", KeywordUDTF.class);

// TODO 5 使用自定义UDTF函数对搜索关键词进行拆分
Table keywordTable = tableEnv.sqlQuery("SELECT rowtime, keyword FROM "+ fullwordTable +", LATERAL TABLE(ik_analyze(fullword)) AS T(keyword)");

3 分组、开窗、聚合计算

// TODO 6 分组、开窗、聚合计算
Table resTable = tableEnv.sqlQuery("select " +
        "  DATE_FORMAT(TUMBLE_START(rowtime, INTERVAL '10' SECOND),'yyyy-MM-dd HH:mm:ss') as stt, " +
        "  DATE_FORMAT(TUMBLE_END(rowtime, INTERVAL '10' SECOND),'yyyy-MM-dd HH:mm:ss') as edt, " +
        "  keyword, " +
        "  count(*) ct," +
        "  '"+ GmallConstant.KEYWORD_SEARCH +"' source," +
        "  UNIX_TIMESTAMP() * 1000 as ts" +
        " from " +
        "  "+ keywordTable +" " +
        " group by " +
        "  TUMBLE(rowtime, INTERVAL '10' SECOND),keyword ");

4 转换为流并写入ClickHouse

(1)在ClickHouse中创建关键词统计表

create table keyword_stats_2022 (
    stt DateTime,
    edt DateTime,
    keyword String ,
    source String ,
    ct UInt64 ,
    ts UInt64
)engine =ReplacingMergeTree( ts)
        partition by  toYYYYMMDD(stt)
        order by  ( stt,edt,keyword,source );

(2)封装KeywordStats实体类

package com.hzy.gmall.realtime.beans;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * Desc: 关键词统计实体类
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class KeywordStats {
    
    
    private String keyword;
    private Long ct;
    private String source;
    private String stt;
    private String edt;
    private Long ts;
}

(3)在主程序中转换流并写入ClickHouse

// TODO 7 将表转换为流
DataStream<KeywordStats> keywordStatsDS = tableEnv.toAppendStream(resTable, KeywordStats.class);
keywordStatsDS.print(">>>");

// TODO 8 将流中数据写入ck中
keywordStatsDS.addSink(ClickhouseUtil.getJdbcSink(
        // 字段顺序与实体类中属性顺序要一致
        "insert into keyword_stats_2022(keyword,ct,source,stt,edt,ts) values(?,?,?,?,?,?) "
));

5 整体测试

  • 启动ZK、Kafka、logger.sh、ClickHouse
  • 运行BaseLogApp
  • 运行KeywordStatsApp
  • 运行rt_applog目录下的jar包
  • 查看控制台输出
  • 查看ClickHouse中keyword_stats_2022表数据

二 数据可视化接口

1 设计思路

之前数据分层处理,最后把轻度聚合的结果保存到ClickHouse中,主要的目的就是提供即时的数据查询、统计、分析服务。这些统计服务一般会用两种形式展现,一种是为专业的数据分析人员的BI工具,一种是面向非专业人员的更加直观的数据大屏。

以下主要是面向百度的sugar的数据大屏服务的接口开发。

2 需求梳理

(1)效果图

在这里插入图片描述

(2)分析可视化大屏

在可视化大屏中每个组件都需要一个单独的接口,图中一共涉及8个组件。

组件名称 组件 查询指标 对应的数据表
总成交金额 数字翻牌 订单总金额 product_stats
省市热力图查询 热力图 省市分组订单金额 province_stats
分时流量 折线图 UV分时数 PV分时数 新用户分时数 visitor_stats
品牌TopN 水平柱状图 按品牌分组订单金额 product_stats
品类分布 饼状图 按品类分组订单金额 product_stats
热词字符云 字符云 关键词分组计数 keyword_stats
流量表格 交叉透视表 UV数(新老用户) PV数(新老用户) 跳出率(新老用户) 平均访问时长 (新老用户) 平均访问页面数(新老用户) visitor_stats
热门商品 轮播表格 按SPU分组订单金额 product_stats

(3)接口执行过程

在这里插入图片描述

之前实现了DWS层计算后写入到ClickHouse中,接下来就是要为可视化大屏服务,提供一个数据接口用来查询ClickHouse中的数据。这里主要有两项工作

  • 配置可视化大屏服务。
  • 编写数据查询接口以供可视化大屏进行访问。

三 Sugar数据大屏

1 产品介绍

Sugar是百度云推出的敏捷 BI 和数据可视化平台,目标是解决报表和大屏的数据 BI 分析和可视化问题,解放数据可视化系统的开发人力。

扫描二维码关注公众号,回复: 15093421 查看本文章

2 使用入口

https://cloud.baidu.com/product/sugar.html

3 创建数据大屏

  • 点击【立即使用】后,登录百度账号

  • 首先创建组织

  • 创建中选择产品【大屏尝鲜版】,首次使用有一个月的试用期

  • 新建好组织后选择【进入组织】

在这里插入图片描述

  • 然后进入默认的【第一个空间】

  • 在空间中选择【待创建大屏】后的【新建】

在这里插入图片描述

  • 选择大屏的模板

  • 可以选空模板,也可以根据现有的模板进行修改

(8) 可以选空模板,也可以根据现有的模板进行修改

  • 这里选择空白模板,并指定大屏的名称

在这里插入图片描述

  • 进入大屏的编辑窗口

四 总成交金额接口

1 Sugar组件:数字翻牌器

(1)添加组件

从大屏的编辑器上方选择【指标】→【数字翻牌器】

在这里插入图片描述

(3)查询组件需要的数据格式

在数据绑定的位置选择【静态JSON】,可以看到数据需要的JSON格式

(4)接口访问路径以及返回格式

1.1.4 接口访问路径以及返回格式

  • 访问路径:/api/sugar/gmv
  • 返回格式
{
  "status": 0,
  "data": 1201012.694507823
}

(5)执行SQL

a product_stats_2022表中数据

在这里插入图片描述

b product_stats_2022表结构

在这里插入图片描述

c SQL语句

toYYYYMMDD:将Date或DateTime转换为包含年份和月份编号的UInt32类型的数字(YYYY * 10000 + MM * 100 + DD)。

select sum(order_amount) order_amount from product_stats_2022 where toYYYYMMDD(stt)=20221215;

2 数据接口实现

(1)创建数据接口模块

a 在gmall2022-parent项目下创建新的SpringBoot模块gmall2022-publisher

在这里插入图片描述

可以先不选择依赖,之后统一在pom.xml中添加

b 在pom.xml文件中添加需要的依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.hzy.gmall.publisher</groupId>
    <artifactId>gmall2022-publisher</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gmall2022-publisher</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.11</version>
        </dependency>

        <dependency>
            <groupId>ru.yandex.clickhouse</groupId>
            <artifactId>clickhouse-jdbc</artifactId>
            <version>0.1.55</version>
        </dependency>
    </dependencies>


    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(2)代码分层结构

a 代码结构

分层 处理内容
controller 控制层 SugarController 查询交易额接口及返回参数处理
service 服务层 ProductStatsService ProductStatsServiceImpl 查询商品统计数据
mapper 数据映射层 ProductStatsMapper 编写SQL查询商品统计表

b 修改Springboot核心配置文件 application.properties

server.port=8070
#配置ClickHouse驱动以及URL
spring.datasource.driver-class-name=ru.yandex.clickhouse.ClickHouseDriver
spring.datasource.url=jdbc:clickhouse://hadoop101:8123/default

c 创建包结构

在这里插入图片描述

(3)代码分层实现

a Mapper层:创建ProductStatsMapper接口

package com.hzy.gmall.publisher.mapper;
/**
 * 商品统计Mapper接口
 */
public interface ProductStatsMapper {
    
    
    // 获取某天商品的总交易额
    @Select("select sum(order_amount) order_amount from product_stats_2022 where toYYYYMMDD(stt)=#{date}")
    BigDecimal selectGMV(Integer date);
}

b 在Application中添加@MapperScan的注解

package com.hzy.gmall.publisher;

@SpringBootApplication
@MapperScan(basePackages = "com.hzy.gmall.publisher.mapper")
public class Gmall2022PublisherApplication {
    
    

    public static void main(String[] args) {
    
    
        SpringApplication.run(Gmall2022PublisherApplication.class, args);
    }

}

c Service层:创建ProductStatsService接口

package com.hzy.gmall.publisher.service;
/**
 * 商品统计service接口
 */
public interface ProductStatsService {
    
    
    // 获取某天的总交易额
    BigDecimal getGMV(Integer date);
}

d Service层:创建ProductStatsServiceImpl实现类

package com.hzy.gmall.publisher.service.impl;
/**
 * 商品统计service接口实现类
 */
@Service
public class ProductStatsServiceImpl implements ProductStatsService{
    
    

    @Autowired
    private ProductStatsMapper productStatsMapper;

    @Override
    public BigDecimal getGMV(Integer date) {
    
    
        return productStatsMapper.selectGMV(date);
    }
}

e Controller层:创建SugarController类

该类主要接收用户请求,并做出响应。根据sugar不同的组件,返回不同的格式。

package com.hzy.gmall.publisher.controller;
/**
 * 大屏展示控制层
 */
@RestController
@RequestMapping("/api/sugar")
public class SugarController {
    
    

    @Autowired
    private ProductStatsService productStatsService;

    @RequestMapping("/gmv")
    public String getGMV(@RequestParam(value = "date",defaultValue = "0") Integer date){
    
    
        if (date == 0){
    
    
            date = now();
        }

        // 调用service获取总交易额
        BigDecimal gmv = productStatsService.getGMV(date);

        String json = "{\"status\": 0,\"data\": "+gmv+"}";
        
        return json;
    }

    // 获取当前日期
    private Integer now() {
    
    
        String yyyyMMdd = DateFormatUtils.format(new Date(), "yyyyMMdd");
        return Integer.valueOf(yyyyMMdd);
    }
}

(4)测试本地接口

a 启动SpringBoot应用程序

用浏览器访问测试接口

b 输出结果

输出结果一:

在这里插入图片描述

输出结果二:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43923463/article/details/128430503