在日常的开发中,最常用的数据格式是 JSON ,并且有的时候 JSON 的格式是非常复杂的(嵌套的格式),那在 Flink SQL 中进行解析的时候也会相当麻烦一点,下面将会演示如何在 DDL 里面定义 Map、Array、Row 类型的数据,以及在 SQL 里面如何获里面的值 数据格式如下: 以下数据完全是自己造的,没有任何实际含义

在日常的开发中,最常用的数据格式是 JSON ,并且有的时候 JSON 的格式是非常复杂的(嵌套的格式),那在 Flink SQL 中进行解析的时候也会相当麻烦一点,下面将会演示如何在 DDL 里面定义 Map、Array、Row 类型的数据,以及在 SQL 里面如何获里面的值


数据格式如下:


以下数据完全是自己造的,没有任何实际含义


{
 "funcName": "test",
 "data": {
  "snapshots": [{
   "content_type": "application/x-gzip-compressed-jpeg",
   "url": "https://blog.csdn.net/xianpanjia4616"
  "audio": [{
   "content_type": "audio/wav",
   "url": " https://bss.csdn.net/m/topic/blog_star2020/detail?username=xianpanjia4616"
 "resultMap": {
  "result": {
   "cover": "/data/test/log.txt"
  "isSuccess": true
 "meta": {
  "video_type": "normal"
 "type": 2,
 "timestamp": 1610549997263,
 "arr": [{
  "address": "北京市海淀区",
  "city": "beijing"
  "address": "北京市海淀区",
  "city": "beijing"
  "address": "北京市海淀区",
  "city": "beijing"
 "map": {
  "flink": 456
 "doublemap": {
  "inner_map": {
   "key": 123
}


上面的数据包含了 Map、Array、Row 等类型, 对于这样的数据格式,在建表 DDL 里面应该如何定义呢?


定义 DDL


CREATE TABLE kafka_source (
    funcName STRING,
    data ROW<snapshots ARRAY<ROW<content_type STRING,url STRING>>,audio ARRAY<ROW<content_type STRING,url STRING>>>,
    resultMap ROW<`result` MAP<STRING,STRING>,isSuccess BOOLEAN>,
    meta  MAP<STRING,STRING>,
    `type` INT,
    `timestamp` BIGINT,
    arr ARRAY<ROW<address STRING,city STRING>>,
    map MAP<STRING,INT>,
    doublemap MAP<STRING,MAP<STRING,INT>>,
    proctime as PROCTIME()
) WITH (
    'connector' = 'kafka', -- 使用 kafka connector
    'topic' = 'test',  -- kafka topic
    'properties.bootstrap.servers' = 'master:9092,storm1:9092,storm2:9092',  -- broker连接信息
    'properties.group.id' = 'jason_flink_test', -- 消费kafka的group_id
    'scan.startup.mode' = 'latest-offset',  -- 读取数据的位置
    'format' = 'json',  -- 数据源格式为 json
    'json.fail-on-missing-field' = 'true', -- 字段丢失任务不失败
    'json.ignore-parse-errors' = 'false'  -- 解析失败跳过
)


解析 SQL


select
funcName,
doublemap['inner_map']['key'],
count(data.snapshots[1].url),
`type`,
TUMBLE_START(proctime, INTERVAL '30' second) as t_start
from kafka_source
group by TUMBLE(proctime, INTERVAL '30' second),funcName,`type`,doublemap['inner_map']['key']


SQL 运行的结果


4> (true,test,123,6,2,2021-01-15T03:31)
4> (false,test,123,6,2,2021-01-15T03:31)
4> (true,test,123,8,2,2021-01-15T03:31)
4> (false,test,123,8,2,2021-01-15T03:31)
4> (true,test,123,10,2,2021-01-15T03:31)
4> (false,test,123,10,2,2021-01-15T03:31)
4> (true,test,123,13,2,2021-01-15T03:31)
4> (false,test,123,13,2,2021-01-15T03:31)
4> (true,test,123,15,2,2021-01-15T03:31)
4> (true,test,123,3,2,2021-01-15T03:31:30)


说明数据都可以正常的解析出来,如果遇到更加复杂的 JSON 格式的数据,只需要比葫芦画瓢就可以了,在复杂的格式都不是问题.


数据类型映射


目前,JSON 模式总是从表模式派生。目前还不支持显式定义 JSON 模式。Flink JSON 格式使用 jackson databind API 来解析和生成JSON 字符串。下表列出了从 Flink 类型到 JSON 类型的映射。


image


注意事项:


Json 中的每个 {} 都需要用 Row 类型来表示


Json 中的每个 [] 都需要用 Arrary 类型来表示


数组的下标是从 1 开始的不是 0 如上面 SQL 中的 data.snapshots[1].url


关键字在任何地方都需要加反引号 如上面 SQL 中的 `type`


select 语句中的字段类型和顺序一定要和结果表的字段类型和顺序保持一致


UDF 可以直接在建表语句中使用


Android:解析Json异常 Expected a string but was BEGIN_OBJECT at
今天解析后端数据时,发现了这个报错:Expected BEGIN_OBJECT but was STRING at 看来是自己哪儿解析错误了。 因为数据的特殊性,后端返回的Json串里面可能还会有Json数据,可能嵌套了三次层,
如何使用Request方法发送Post请求、JSON文件介绍、Python中的JSON数据以及获取到的JSON数据的解析。
如何使用Request方法发送Post请求、JSON文件介绍、Python中的JSON数据以及获取到的JSON数据的解析。