首页 > 数据库 >JSON日志处理 | 基于SparkSql实现

JSON日志处理 | 基于SparkSql实现

时间:2024-10-25 09:17:52浏览次数:7  
标签:purchase users json cart JSON SparkSql 日志 id

目录

0 主要JSON处理 函数

1 JSON处理函数使用

2 案例分析

3 小结


0 主要JSON处理 函数


get_json_object: 提取单个 JSON 字段
json_tuple: 同时提取多个 JSON 字段
from_json: JSON 字符串转结构化数据
to_json: 结构化数据转 JSON 字符串
schema_of_json: 推断 JSON schema

1 JSON处理函数使用

get_json_object函数允许我们使用JSONPath表达式从JSON字符串中提取特定字段。

语法:

get_json_object(json_str, path)

例:

SELECT get_json_object('{"name":"John", "age":30}', '$.name') AS name;
-- 输出: John


这个函数特别适合从复杂JSON中提取单个字段。

json_tuple: 多字段提取神器

当需要同时提取多个JSON字段时,json_tuple函数是你的最佳选择。

语法:

json_tuple(json_str, key1, key2, ...)

示例:

SELECT json_tuple('{"name":"John", "age":30, "city":"New York"}', 'name', 'age') AS (name, age);
-- 输出: John, 30


json_tuple能显著提高多字段提取的效率,减少重复解析。

 

to_json: 结构化数据转JSON的便捷工具 

from_json相反,to_json函数将结构化数据转换回JSON字符串。 

语法:

to_json(expr[, options])
 

示例:

SELECT to_json(struct("John" AS name, 30 AS age)) AS json_data;
-- 输出: {"name":"John","age":30}

 在数据导出或API响应生成时,这个函数尤为实用。

schema_of_json: JSON Schema推断神器 

schema_of_json函数能自动推断JSON字符串的schema,省去手动定义的麻烦。

语法:

schema_of_json(json_str)

 示例:

SELECT schema_of_json('{"name":"John", "age":30, "scores":[85, 90, 92]}') AS json_schema;

这个函数在处理未知结构的JSON数据时特别有价值。

JSON数组处理:size和explode函数

处理JSON数组是一个常见需求,SparkSQL为此提供了强大的支持。

size函数:获取数组长度
size函数可以用来获取JSON数组的长度。

语法:

size(json_array)

示例: 

SELECT size(from_json('{"scores":[85, 90, 92]}', 'struct<scores:array<int>>').scores) AS array_size;
-- 输出: 3

 

explode函数:展开JSON数组
explode函数能将JSON数组展开为多行,方便进行后续分析。

语法:

explode(array)
 

示例: 

SELECT explode(from_json('{"scores":[85, 90, 92]}', 'struct<scores:array<int>>').scores) AS score;
-- 输出:
-- 85
-- 90
-- 92

2 案例分析

JSON函数实战:电商用户行为分析

数据样例

{
  "user_id": 1001,
  "session_id": "a1b2c3d4",
  "timestamp": "2024-08-01T10:30:00Z",
  "events": [
    {"type": "view", "product_id": "P001", "category": "Electronics"},
    {"type": "add_to_cart", "product_id": "P001", "quantity": 1},
    {"type": "purchase", "product_id": "P001", "price": 599.99}
  ]
}

数据处理和分析

-- 1. 提取用户ID和会话ID
WITH parsed_logs AS (
  SELECT
    get_json_object(value, '$.user_id') AS user_id,
    get_json_object(value, '$.session_id') AS session_id,
    get_json_object(value, '$.timestamp') AS event_time,
    explode(from_json(get_json_object(value, '$.events'), 'array<struct<type:string,product_id:string,category:string,quantity:int,price:double>>')) AS event
  FROM user_logs
),

-- 2. 分析用户行为
user_behavior AS (
  SELECT
    user_id,
    session_id,
    COUNT(CASE WHEN event.type = 'view' THEN 1 END) AS view_count,
    COUNT(CASE WHEN event.type = 'add_to_cart' THEN 1 END) AS cart_add_count,
    COUNT(CASE WHEN event.type = 'purchase' THEN 1 END) AS purchase_count,
    SUM(CASE WHEN event.type = 'purchase' THEN event.price ELSE 0 END) AS total_purchase_amount
  FROM parsed_logs
  GROUP BY user_id, session_id
),

-- 3. 计算转化率
conversion_rates AS (
  SELECT
    COUNT(DISTINCT CASE WHEN view_count > 0 THEN user_id END) AS users_with_views,
    COUNT(DISTINCT CASE WHEN cart_add_count > 0 THEN user_id END) AS users_with_cart_adds,
    COUNT(DISTINCT CASE WHEN purchase_count > 0 THEN user_id END) AS users_with_purchases
  FROM user_behavior
)

-- 4. 输出分析结果
SELECT
  users_with_views AS total_active_users,
  users_with_cart_adds AS users_adding_to_cart,
  users_with_purchases AS users_making_purchase,
  ROUND(users_with_cart_adds / users_with_views * 100, 2) AS view_to_cart_rate,
  ROUND(users_with_purchases / users_with_cart_adds * 100, 2) AS cart_to_purchase_rate,
  ROUND(users_with_purchases / users_with_views * 100, 2) AS overall_conversion_rate
FROM conversion_rates;

解释:

  • parsed_logs: 使用get_json_object提取顶层字段,并用explode和from_json展开嵌套的事件数组。
  • user_behavior: 统计每个用户会话的各类行为次数和总购买金额。
  • conversion_rates: 计算不同行为的用户数量。

输出结果如下:

+------------------+---------------------+----------------------+-----------------+----------------------+------------------------+
|total_active_users|users_adding_to_cart|users_making_purchase|view_to_cart_rate|cart_to_purchase_rate|overall_conversion_rate|
+------------------+---------------------+----------------------+-----------------+----------------------+------------------------+
|             10000|                6000|                 3000|            60.00|                50.00|                  30.00|
+------------------+---------------------+----------------------+-----------------+----------------------+------------------------+

进一步分析

我们还可以深入分析最受欢迎的产品类别:

SELECT
  event.category,
  COUNT(*) AS view_count,
  SUM(CASE WHEN event.type = 'purchase' THEN 1 ELSE 0 END) AS purchase_count,
  ROUND(SUM(CASE WHEN event.type = 'purchase' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) AS conversion_rate
FROM parsed_logs
WHERE event.category IS NOT NULL
GROUP BY event.category
ORDER BY view_count DESC
LIMIT 5;

3 小结

在大数据时代,JSON 格式因其灵活性和广泛应用而成为数据处理的重要一环。SparkSQL 提供了强大的内置 JSON 函数,让我们能够高效地处理复杂的 JSON 数据。本文全面总结了这些函数的使用方法、优化技巧及实战应用。 

本文核心要点

  • 灵活运用函数组合:如 get_json_object 与 explode 配合使用
  • 性能优先:合理使用 schema 定义,避免过度依赖自动推断
  • 数据层次化处理:使用 CTE (Common Table Expression) 使查询更清晰
  • 商业洞察导向:从原始数据中提取有价值的业务指标

如果您觉得本文还不错,对你有帮助,那么不妨可以关注一下我的数字化建设实践之路专栏,这里的内容会更精彩。

专栏 原价99,现在活动价59.9,按照阶梯式增长,还差5个人上升到69.9,最终恢复到原价

专栏优势:

(1)一次收费持续更新。

(2)实战中总结的SQL技巧,帮助SQLBOY 在SQL语言上有质的飞越,无论你应对业务难题及面试都会游刃有余【全网唯一讲SQL实战技巧,方法独特

(3)实战中数仓建模技巧总结,让你认识不一样的数仓。【数据建模+业务建模,不一样的认知体系】(如果只懂数据建模而不懂业务建模,数仓体系认知是不全面的

(4)数字化建设当中遇到难题解决思路及问题思考。

 

我的 专栏具体链接如下:

数字化建设通关指南_莫叫石榴姐的博客-CSDN博客

https://blog.csdn.net/godlovedaniel/category_12706766.html?fromshare=blogcolumn&sharetype=blogcolumn&sharerId=12706766&sharerefer=PC&sharesource=godlovedaniel&sharefrom=from_link

标签:purchase,users,json,cart,JSON,SparkSql,日志,id
From: https://blog.csdn.net/godlovedaniel/article/details/143170926

相关文章

  • 使用mysqlbinlog 备份 binlog日志文件
    使用mysqlbinlog备份二进制日志文件默认情况下,mysqlbinlog读取二进制日志文件并以文本格式显示其内容。这使您能够更轻松地检查文件中的事件并重新执行它们(例如,通过将输出用作mysql的输入)。mysqlbinlog可以直接从本地文件系统读取日志文件,或者,--read-from-remote-server它可......
  • 网关点表&&全局点表json文件使用(拓展性实现方法)
    全局点表点表作用每一个网关中都会有配置点表,它会在里面写入一些网关运行过程中所需要的配置项,比如连接的服务器地址、当前固件版本号等。而点表最重要的作用就是定义网关需要采集或者处理的设备点抽象,实际开发中我们会将每个需要关注的终端设备抽象成一个具体的数据点,这......
  • SpringBoot入门到精通(十三)日志:别小看它,否则吃亏的是自己!学会你也可以设计架构
    别小看他,当你面对的时候,就会知道,多么痛的领悟!如何在SpringBoot中使用Logback记录详细的日志?整合LogBack,Log4J...等,是不是很多方法!但需要注意,我讲的可能和你是一样的,但也是不一样的。常见日志级别:高---低排列TRACE:描述:最详细的日志级别,通常用于开发和调试阶段......
  • 2024/10/24日 日志 --》关于Mybatis的学习笔记整理 - 环境与性质
    步入了Mybatis的学习之中,以下为其相关内容的细化笔记整理点击查看代码--MyBatis--·MyBatis是一款优秀的持久层框架,用于简化JDBC开发--·官网:https://mybatis.net.cn/ --持久层:--·负责将数据保存到数据库的那一层代码--JavaEE三层架构:表现层、业务层、持久层分......
  • Linux 定时清理日志
    在Linux系统中,你可以使用cron作业来定时运行一个清理日志的脚本。以下是一个简单的示例,包括一个用于清理日志的脚本和一个用于设置定时任务的cron作业。1.创建清理日志的脚本首先,创建一个脚本文件,例如cleanup_logs.sh,并赋予其可执行权限。这个脚本将删除指定目录下超过......
  • 海康威视AI开放平台训练数据集导入问题---解决导入自己数据集的问题(txt转json格式)
    一、问题导入首先我们先进入到开放平台中,选择物体检测最近在做一个项目,需要使用到海康威视AI开放平台来训练数据集,但是刚开始遇到了一个问题就是导入自己的数据集(txt格式转成了json格式)为啥没有用,后面查看相关文档,解决了导入自己数据集的问题,就不用在平台里标注了。二、探......
  • Golang 中使用 JSON 的一些小技巧
    临时忽略struct字段typeUserstruct{Emailstring`json:"email"`Passwordstring`json:"password"`//manymorefields…}临时忽略掉Password字段json.Marshal(struct{*UserPasswordbool`json:"password,omitempty"`}{Us......
  • linux硬盘日志清理
    日志文件清理#!/bin/bash#定义需要检查的目录directories=("/home/logs/archived"\"/data/logs")#获取当前硬盘分区的使用情况df_output=$(df--output=pcent/data|tail-n1|tr-d'%')#获取当前时间current_time=$(date"+%Y-%m-%d%H:......
  • 如何将rust日志输出到android终端
    本博客所有文章除特别声明外,均采用CCBY-NC-SA4.0许可协议。转载请注明来自唯你背景在Rust中,使用println!打印日志时,输出实际上是发送到标准输出(stdout),而AndroidLogcat专门用于处理和显示应用程序的日志信息,此环境下标准输出实现被重新定义。这意味着Rust日志输出不......
  • 一个著名的日志系统是怎么设计出来的
    原文:一个著名的日志系统是怎么设计出来的1前言Java帝国在诞生之初就提供了集合、线程、IO、网络等常用功能,从C和C++领地那里吸引了大量程序员过来加盟,但是却有意无意地忽略了一个重要的功能:输出日志。对于这一点,IO大臣其实非常清楚,日志是个很重要的东西,因为程序运行起......