当前位置: 首页 > web >正文

用 DuckDB 高效分析 JSON 数据:从入门到实战

解析 JSON 文件进行分析常常充满挑战。无论你是在处理 API 响应、日志文件,还是应用数据,如果没有合适的工具,分析 JSON 都会非常耗时。

借助 DuckDB,你可以直接用 SQL 查询复杂的 JSON 文件,无需编写复杂的解析代码或搭建重量级数据库环境,就能高效分析 JSON 数据。

Analyzing JSON Data with DuckDB and SQL

本文将带你了解如何使用 DuckDB 高效地查询和分析 JSON 数据,内容涵盖:

  • 在你的系统上安装和配置 DuckDB

  • 加载并查询 JSON 数据

  • 处理嵌套的 JSON 结构

  • 操作 JSON 数组和复杂对象

我们将基于真实的电商数据进行演示,介绍可立即应用于实际项目的技巧。让我们开始吧!

🔗 [GitHub 上的代码链接]


安装与启动 DuckDB

DuckDB 轻量且易于安装。下面是安装与运行 DuckDB 的步骤:

如果你使用的是 Linux 发行版,并希望通过命令行使用 duckdb,请执行以下操作:

安装 DuckDB:

$ curl https://install.duckdb.org | sh

添加到 PATH:

$ export PATH='/home/user/.duckdb/cli/latest':$PATH

通过命令行启动 DuckDB:

$ duckdb

你将看到如下界面:

v1.2.2 7c039464e4
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D

现在你已经准备就绪!

🔗 你可以查看 DuckDB 的安装文档,了解其他平台的安装指南。


使用示例 JSON 数据

我们将创建一个实用的电商数据集进行演示。该 JSON 结构包含订单、客户信息和产品明细,类似于真实电商 API 返回的数据。

📁 示例 JSON 数据存放于 ecommerce_data.json 文件中。


加载与查询 JSON 数据

现在,让我们把 JSON 数据加载到 DuckDB,并执行一些基础查询。

加载 JSON 数据

连接到 DuckDB 后,运行以下命令:

-- 从 JSON 文件创建表
CREATE TABLE ecommerce AS 
SELECT * FROM read_json_auto('ecommerce_data.json');

此命令会读取 JSON 文件并自动推断数据表结构。read_json_auto 函数还能识别嵌套结构和数组。

确认数据是否正确加载:

-- 查看数据
SELECT * FROM ecommerce;

你应该会看到整个 JSON 数据以结构化表格的形式展现:

┌──────────┬───┬──────────────────────┬──────────────────────┐
│ order_id │ … │        items         │       payment        │
│ varchar  │   │ struct(product_id …  │ struct("method" va…  │
├──────────┼───┼──────────────────────┼──────────────────────┤
│ ORD-1001 │ … │ [{'product_id': PR…  │ {'method': credit_…  │
│ ORD-1002 │ … │ [{'product_id': PR…  │ {'method': paypal,…  │
├──────────┴───┴──────────────────────┴──────────────────────┤
│ 2 rows                                 5 columns (3 shown) │
└────────────────────────────────────────────────────────────┘

基础查询示例

先来几个简单查询:

-- 统计订单数量
SELECT COUNT(*) AS order_count FROM ecommerce;

输出:

┌─────────────┐
│ order_count │
│    int64    │
├─────────────┤
│      2      │
└─────────────┘

提取嵌套字段时,->>'name' 用于从 customer 对象中提取 name 字段文本,->> 返回文本,-> 返回 JSON。

-- 获取订单号及客户姓名
SELECT order_id,customer->>'name' AS customer_name
FROM ecommerce;

输出:

┌──────────┬───────────────┐
│ order_id │ customer_name │
│ varchar  │    varchar    │
├──────────┼───────────────┤
│ ORD-1001 │ Alex Johnson  │
│ ORD-1002 │ Sarah Miller  │
└──────────┴───────────────┘

操作嵌套 JSON 结构

JSON 的一个难点在于处理嵌套对象。比如提取客户地址信息:

-- 提取客户地址信息
SELECT order_id,customer->>'name' AS customer_name,customer->'address'->>'city' AS city,customer->'address'->>'state' AS state
FROM ecommerce;

输出:

┌──────────┬───────────────┬─────────┬─────────┐
│ order_id │ customer_name │  city   │  state  │
│ varchar  │    varchar    │ varchar │ varchar │
├──────────┼───────────────┼─────────┼─────────┤
│ ORD-1001 │ Alex Johnson  │ Boston  │ MA      │
│ ORD-1002 │ Sarah Miller  │ Seattle │ WA      │
└──────────┴───────────────┴─────────┴─────────┘

你可以通过链式箭头操作符深入 JSON 结构。

还可以基于嵌套字段进行筛选:

-- 查找来自西雅图的订单
SELECT order_id,customer->>'name' AS customer_name
FROM ecommerce
WHERE customer->'address'->>'city' = 'Seattle';

输出:

┌──────────┬───────────────┐
│ order_id │ customer_name │
│ varchar  │    varchar    │
├──────────┼───────────────┤
│ ORD-1002 │ Sarah Miller  │
└──────────┴───────────────┘

提取支付信息:

-- 获取支付详情
SELECT order_id,payment->>'method' AS payment_method,CAST(payment->>'total' AS DECIMAL) AS total_amount
FROM ecommerce;

输出:

┌──────────┬────────────────┬───────────────┐
│ order_id │ payment_method │ total_amount  │
│ varchar  │    varchar     │ decimal(18,3) │
├──────────┼────────────────┼───────────────┤
│ ORD-1001 │ credit_card    │       179.970 │
│ ORD-1002 │ paypal         │       137.960 │
└──────────┴────────────────┴───────────────┘

注意,这里通过 CAST 将 total 转为 decimal,便于数值运算。


处理数组与复杂对象

JSON 数组需要特殊处理。来看如何展开每笔订单中的 items:

-- 将 items 数组展开为多行
SELECT order_id,customer->>'name' AS customer_name,unnest(items) AS item
FROM ecommerce;

输出:

┌──────────┬───────────────┬───────────────────────────────────────────────────┐
│ order_id │ customer_name │                       item                        │
│ varchar  │    varchar    │ struct(product_id varchar, "name" varchar, cate…  │
├──────────┼───────────────┼───────────────────────────────────────────────────┤
│ ORD-1001 │ Alex Johnson  │ {'product_id': PROD-501, 'name': Wireless Headp…  │
│ ORD-1001 │ Alex Johnson  │ {'product_id': PROD-245, 'name': Smartphone Cas…  │
│ ORD-1002 │ Sarah Miller  │ {'product_id': PROD-103, 'name': Coffee Maker, …  │
│ ORD-1002 │ Sarah Miller  │ {'product_id': PROD-107, 'name': Coffee Beans P…  │
└──────────┴───────────────┴───────────────────────────────────────────────────┘

unnest() 函数将 JSON 数组的每个元素转换为一行,便于 SQL 分析。

进一步提取每个 item 的字段:

-- 提取每个商品明细
SELECT order_id,customer->>'name' AS customer_name,item->>'name' AS product_name,item->>'category' AS category,CAST(item->>'price' AS DECIMAL) AS price,CAST(item->>'quantity' AS INTEGER) AS quantity
FROM (SELECT order_id,customer,unnest(items) AS itemFROM ecommerce
) AS unnested_items;

输出:

┌──────────┬───────────────┬───┬───────────────┬──────────┐
│ order_id │ customer_name │ … │     price     │ quantity │
│ varchar  │    varchar    │   │ decimal(18,3) │  int32   │
├──────────┼───────────────┼───┼───────────────┼──────────┤
│ ORD-1001 │ Alex Johnson  │ … │       129.990 │        1 │
│ ORD-1001 │ Alex Johnson  │ … │        24.990 │        2 │
│ ORD-1002 │ Sarah Miller  │ … │        89.990 │        1 │
│ ORD-1002 │ Sarah Miller  │ … │        15.990 │        3 │
├──────────┴───────────────┴───┴───────────────┴──────────┤
│ 4 rows                              6 columns (4 shown) │
└─────────────────────────────────────────────────────────┘

这里通过子查询展开 items 再提取字段,是处理嵌套数组的关键。

做一些数据分析:

-- 计算每个订单的总价值与商品数量
SELECT order_id,customer->>'name' AS customer_name,CAST(payment->>'total' AS DECIMAL) AS order_total,json_array_length(items) AS item_count
FROM ecommerce;

输出:

┌──────────┬───────────────┬───────────────┬────────────┐
│ order_id │ customer_name │  order_total  │ item_count │
│ varchar  │    varchar    │ decimal(18,3) │   uint64   │
├──────────┼───────────────┼───────────────┼────────────┤
│ ORD-1001 │ Alex Johnson  │       179.970 │          2 │
│ ORD-1002 │ Sarah Miller  │       137.960 │          2 │
└──────────┴───────────────┴───────────────┴────────────┘

json_array_length() 可用于获取每个订单的商品数量。

-- 按商品类别统计平均单价
SELECT item->>'category' AS category,AVG(CAST(item->>'price' AS DECIMAL)) AS avg_price
FROM (SELECT unnest(items) AS itemFROM ecommerce
) AS unnested_items
GROUP BY category
ORDER BY avg_price DESC;

输出:

┌─────────────────┬───────────┐
│    category     │ avg_price │
│     varchar     │  double   │
├─────────────────┼───────────┤
│ Electronics     │    129.99 │
│ Kitchen         │     89.99 │
│ Accessories     │     24.99 │
│ Food & Beverage │     15.99 │
└─────────────────┴───────────┘

该查询先展开 items,再按类别分组计算平均价格。


总结

你已掌握使用 DuckDB 分析 JSON 数据的核心技巧。这些方法能帮你轻松应对大多数 JSON 数据分析需求。DuckDB 结合了熟悉的 SQL 语法和强大的 JSON 专用函数,让你高效处理复杂数据。

下次遇到庞杂的 JSON 数据集时,希望你能跳过繁琐的解析步骤,直奔高效分析!

http://www.xdnf.cn/news/3735.html

相关文章:

  • 机器学习常用评价指标
  • P1004 [NOIP 2000 提高组] 方格取数
  • api补充
  • 在GPU集群上使用Megatron-LM进行高效的大规模语言模型训练
  • 有效的字母异位词(简单)
  • 闭包(Closure)及其作用和影响
  • 《ATPL地面培训教材13:飞行原理》——第5章:升力
  • 【算法应用】基于灰狼算法优化深度信念网络回归预测(GWO-DBN)
  • C# 运算符重载深度解析:从基础到高阶实践
  • MIT6.S081-lab8
  • 十一岁少年叶珉雪用艺术点亮公益之路 个人原创公益演唱会传递大爱与担当
  • C++类_构造函数
  • DBSCAN对比K-means
  • 软件第三方测试报告:从测试背景目的到方法范围全解析?
  • 域名与官网的迷思:数字身份认证的全球困境与实践解方-优雅草卓伊凡
  • Java 网络安全新技术:构建面向未来的防御体系
  • 【三班网】初中最后一次研学活动纪实
  • 如何提升个人的理解能力?
  • 生成式 AI 的优势
  • 软件管理(安装方式)
  • 【关于LM311实现过零比较器输出波形】2022-9-27
  • 【自然语言处理与大模型】使用Xtuner进行模型合并与导出
  • NHANES指标推荐:triglyceride levels
  • MySQL安装完全指南:从零开始到配置优化(附避坑指南)
  • java_Lambda表达式
  • C++函数详解:从基础到高级应用
  • 二维码批量识别—混乱多张二维码识别-物品分拣—-未来之窗-仙盟创梦IDE
  • 生成式 AI 的阐释
  • 解决Maven项目中报错“java不支持版本6即更高的版本 7”
  • 使用python加edge-tts实现文字转语音