doris:JSON导入数据

news/2025/2/1 0:49:56 标签: json, doris

本文介绍如何在 Doris 中导入 JSON 格式的数据文件。Doris 支持导入标准 JSON 格式数据,通过配置相关参数,可以灵活地处理不同的 JSON 数据结构,并支持从 JSON 数据中抽取字段、处理嵌套结构等场景。

导入方式​

以下导入方式支持 JSON 格式的数据导入:

  • Stream Load
  • Broker Load
  • Routine Load
  • INSERT INTO FROM S3 TVF
  • INSERT INTO FROM HDFS TVF

json-格式">支持的 JSON 格式​

Doris 支持以下三种 JSON 格式:

以 Array 表示的多行数据​

适用于批量导入多行数据,要求:

  • 根节点必须是数组
  • 数组中每个元素是一个对象,表示一行数据
  • 必须设置 strip_outer_array=true

示例数据:

[
    {"id": 123, "city": "beijing"},
    {"id": 456, "city": "shanghai"}
]

// 支持嵌套结构
[
    {"id": 123, "city": {"name": "beijing", "region": "haidian"}},
    {"id": 456, "city": {"name": "beijing", "region": "chaoyang"}}
]

以 Object 表示的单行数据​

适用于单行数据导入,要求:

  • 根节点必须是对象
  • 整个对象表示一行数据

示例数据:

{"id": 123, "city": "beijing"}

// 支持嵌套结构
{"id": 123, "city": {"name": "beijing", "region": "haidian"}}

注意

通常用于 Routine Load 导入方式,如 Kafka 中的单条消息。

以固定分隔符分隔的多行 Object 数据​

适用于批量导入多行数据,要求:

  • 每行是一个完整的 JSON 对象
  • 必须设置 read_json_by_line=true
  • 可通过 line_delimiter 参数指定行分隔符,默认为 \n

示例数据:

{"id": 123, "city": "beijing"}
{"id": 456, "city": "shanghai"}

参数配置​

参数支持情况​

下表列出了各种导入方式支持的 JSON 格式参数:

参数默认值Stream LoadBroker LoadRoutine LoadTVF
json pathsjsonpathsproperties.jsonpathsproperties.jsonpathsjsonpaths
json rootjson_rootproperties.json_rootproperties.json_rootjson_root
strip outer arrayfalsestrip_outer_arrayproperties.strip_outer_arrayproperties.strip_outer_arraystrip_outer_array
read json by linefalseread_json_by_line不支持配置,都为true不支持read_json_by_line, 默认为true
fuzzy parsefalsefuzzy_parseproperties.fuzzy_parse不支持fuzzy_parse
num as stringfalsenum_as_stringproperties.num_as_stringproperties.num_as_stringnum_as_string

注意

  1. Stream Load:参数直接通过 HTTP Header 指定,如:-H "jsonpaths: $.data"
  2. Broker Load:参数通过 PROPERTIES 指定,如:PROPERTIES("jsonpaths"="$.data")
  3. Routine Load:参数通过 PROPERTIES 指定,如:PROPERTIES("jsonpaths"="$.data")
  4. TVF:参数通过 TVF 语句指定,如:S3("jsonpaths"="$.data")

参数说明​

json-path">JSON Path​
  • 作用:指定如何从 JSON 数据中抽取字段
  • 类型:字符串数组
  • 默认值:无,默认使用列名匹配
  • 使用示例:
    -- 基本用法
    ["$.id", "$.city"]
    
    -- 嵌套结构
    ["$.id", "$.info.city", "$.data[0].name"]
    

json-root">JSON Root​
  • 作用:指定 JSON 数据的解析起点
  • 类型:字符串
  • 默认值:无,默认从根节点开始解析
  • 使用示例:
    -- 原始数据
    {
      "data": {
        "id": 123,
        "city": "beijing"
      }
    }
    
    -- 设置 json_root
    json_root = $.data
    

Strip Outer Array​
  • 作用:指定是否去除最外层的数组结构
  • 类型:布尔值
  • 默认值:false
  • 使用示例:
    -- 原始数据
    [
      {"id": 1, "city": "beijing"},
      {"id": 2, "city": "shanghai"}
    ]
    
    -- 设置 strip_outer_array=true
    

json-by-line">Read JSON By Line​
  • 作用:指定是否按行读取 JSON 数据
  • 类型:布尔值
  • 默认值:false
  • 使用示例:
    -- 原始数据(每行一个完整的 JSON 对象)
    {"id": 1, "city": "beijing"}
    {"id": 2, "city": "shanghai"}
    
    -- 设置 read_json_by_line=true
    

Fuzzy Parse​
  • 作用:加速 JSON 数据的导入效率
  • 类型:布尔值
  • 默认值:false
  • 限制:
    • Array 中每行数据的字段顺序必须完全一致
    • 通常与 strip_outer_array 配合使用
  • 性能:可提升 3-5 倍导入效率
Num As String​
  • 作用:指定是否将 JSON 中的数值类型以字符串形式解析
  • 类型:布尔值
  • 默认值:false
  • 使用场景:
    • 处理超出数值范围的大数
    • 避免数值精度损失
  • 使用示例:
    -- 原始数据
    {
      "id": "12345678901234567890",
      "price": "99999999.999999"
    }
    -- 设置 num_as_string=true, price 字段将以字符串形式解析
    
    

json-path-和-columns-的关系">JSON Path 和 Columns 的关系​

在数据导入过程中,JSON Path 和 Columns 各自承担不同的职责:

JSON Path:定义数据抽取规则

  • 从 JSON 数据中按指定路径抽取字段
  • 抽取的字段按 JSON Path 中定义的顺序进行重排列

Columns:定义数据映射规则

  • 将抽取的字段映射到目标表的列
  • 可以进行列的重排和转换

这两个参数的处理过程是串行的:首先 JSON Path 从源数据中抽取字段并形成有序的数据集,然后 Columns 将这些数据映射到表的列中。如果不指定 Columns,抽取的字段将按照表的列顺序直接映射。

使用示例​
json-path">仅使用 JSON Path​

表结构和数据:

-- 表结构
CREATE TABLE example_table (
    k2 int,
    k1 int
);

-- JSON 数据
{"k1": 1, "k2": 2}

导入命令:

curl -v ... -H "format: json" \
    -H "jsonpaths: [\"$.k2\", \"$.k1\"]" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/db_name/table_name/_stream_load

导入结果:

+------+------+
| k1   | k2   |
+------+------+
|    2 |    1 | 
+------+------+

json-path--columns">使用 JSON Path + Columns​

使用相同的表结构和数据,添加 columns 参数:

导入命令:

curl -v ... -H "format: json" \
    -H "jsonpaths: [\"$.k2\", \"$.k1\"]" \
    -H "columns: k2, k1" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/db_name/table_name/_stream_load

导入结果:

+------+------+
| k1   | k2   |
+------+------+
|    1 |    2 | 
+------+------+

字段重复使用​

表结构和数据:

-- 表结构
CREATE TABLE example_table (
    k2 int,
    k1 int,
    k1_copy int
);

-- JSON 数据
{"k1": 1, "k2": 2}

导入命令:

curl -v ... -H "format: json" \
    -H "jsonpaths: [\"$.k2\", \"$.k1\", \"$.k1\"]" \
    -H "columns: k2, k1, k1_copy" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/db_name/table_name/_stream_load

导入结果:

+------+------+---------+
| k2   | k1   | k1_copy |
+------+------+---------+
|    2 |    1 |       1 |
+------+------+---------+

嵌套字段映射​

表结构和数据:

-- 表结构
CREATE TABLE example_table (
    k2 int,
    k1 int,
    k1_nested1 int,
    k1_nested2 int
);

-- JSON 数据
{
    "k1": 1,
    "k2": 2,
    "k3": {
        "k1": 31,
        "k1_nested": {
            "k1": 32
        }
    }
}

导入命令:

curl -v ... -H "format: json" \
    -H "jsonpaths: [\"$.k2\", \"$.k1\", \"$.k3.k1\", \"$.k3.k1_nested.k1\"]" \
    -H "columns: k2, k1, k1_nested1, k1_nested2" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/db_name/table_name/_stream_load

导入结果:

+------+------+------------+------------+
| k2   | k1   | k1_nested1 | k1_nested2 |
+------+------+------------+------------+
|    2 |    1 |         31 |         32 |
+------+------+------------+------------+

使用示例​

本节展示了不同导入方式下的 JSON 格式使用方法。

Stream Load 导入​

# 使用 JSON Path
curl --location-trusted -u <user>:<passwd> \
    -H "format: json" \
    -H "jsonpaths: [\"$.id\", \"$.city\"]" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/example_db/example_table/_stream_load

# 指定 JSON root
curl --location-trusted -u <user>:<passwd> \
    -H "format: json" \
    -H "json_root: $.events" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/example_db/example_table/_stream_load

# 按行读取 JSON
curl --location-trusted -u <user>:<passwd> \
    -H "format: json" \
    -H "read_json_by_line: true" \
    -T example.json \
    http://<fe_host>:<fe_http_port>/api/example_db/example_table/_stream_load

Broker Load 导入​

-- 使用 JSON Path
LOAD LABEL example_db.example_label
(
    DATA INFILE("s3://bucket/path/example.json")
    INTO TABLE example_table
    FORMAT AS "json"
    PROPERTIES
    (
        "jsonpaths" = "[\"$.id\", \"$.city\"]"
    )
)
WITH S3 
(
    ...
);

-- 指定 JSON root
LOAD LABEL example_db.example_label
(
    DATA INFILE("s3://bucket/path/example.json")
    INTO TABLE example_table
    FORMAT AS "json"
    PROPERTIES
    (
        "json_root" = "$.events"
    )
)
WITH S3 
(
    ...
);

Routine Load 导入​

-- 使用 JSON Path
CREATE ROUTINE LOAD example_db.example_job ON example_table
PROPERTIES
(
    "format" = "json",
    "jsonpaths" = "[\"$.id\", \"$.city\"]"
)
FROM KAFKA
(
    ...
);

TVF 导入​

-- 使用 JSON Path
INSERT INTO example_table
SELECT *
FROM S3
(
    "uri" = "s3://bucket/example.json",
    "format" = "json",
    "jsonpaths" = "[\"$.id\", \"$.city\"]",
    ...
);

-- 指定 JSON root 
INSERT INTO example_table
SELECT *
FROM S3
(
    "uri" = "s3://bucket/example.json",
    "format" = "json",
    "json_root" = "$.events",
    ...
);


http://www.niftyadmin.cn/n/5838929.html

相关文章

应用程序中处理文件上传的方法

在应用程序中处理文件上传通常涉及以下几个步骤: 一、前端准备 前端负责收集文件,并通过 HTTP 请求将其发送到服务器。常见的方法包括: ①HTML <form>; 表单:使用 enctype="multipart/form-data" 属性指定表单支持文件上传。 ②JavaScript (AJAX):可以使…

第九章 D - E 开头的术语

文章目录 第九章 D - E 开头的术语显示格式 (display format)分布式数据库 (distributed database)DMNNET点语法 (dot syntax) 以 E 开头的术语.可嵌入类 (embeddable class)内嵌 HTML (embedded HTML)内嵌对象 (embedded object)内嵌 SQL (embedded SQL)空字符串 (empty strin…

DBO优化GRNN回归预测matlab

蜣螂优化算法&#xff0c;英文名为 Dung Beetle Optimizer&#xff0c;简称 DBO&#xff0c;是于 2022 年末提出的一种全新群智能优化算法。该算法的灵感主要来源于蜣螂的滚球、跳舞、觅食、偷窃以及繁殖等行为。 本次所使用的数据为 Excel 格式的股票预测数据。这些数据被划分…

Pdf to forms如何实现?如何在3分钟内将PDF自动转换为Microsoft Forms

通过将杂乱的文件转换为标准化表单&#xff0c;简化数据收集——无需手动操作。 问题&#xff1a;为什么非标准文件会破坏您的工作流程 每天&#xff0c;企业和教育工作者都淹没在非结构化数据中&#xff1a;PDF报告、CSV导出或保存为TXT文件的手写笔记。手动将这些数据复制到…

(undone) MIT6.S081 2023 学习笔记 (Day7: LAB6 Multithreading)

网页&#xff1a;https://pdos.csail.mit.edu/6.S081/2023/labs/thread.html 任务1&#xff1a;Uthread: switching between threads (moderate) (doing) 在这个练习中&#xff0c;你将设计一个用户级线程系统中的上下文切换机制&#xff0c;并实现它。为了帮助你开始&#xf…

我的求职面经:(1)C++里指针和数组的区别

经典问题&#xff1a; char s1[]"hello"; char *s2"hello"; 1、s1的值是放在栈上的&#xff0c;值是可以修改的&#xff0c;而hello是一个字符串常量放在静态存储区是不能修改的。 2、内存大小不一样 #include<stdio.h>int main(){char s1[]&quo…

python-leetcode-路径总和

112. 路径总和 - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:de…

在K8s中部署动态nfs存储provisioner

背景 之前&#xff0c;我已经在一台worker node上安装了local lvm 的provisioner来模拟需要本地高IOPS的数据库等stafeful应用的实现。 为了后续给虚拟机里的K8s集群安装可用的metrics和logs监控系统&#xff08;metrics和logs的时序数据库需要永久存储&#xff09;&#xff0…