Spark SQL中的from_json函数详解
Spark SQL中的from_json
函数详解
在Spark SQL中,from_json
是一个用于解析JSON数据的函数,主要用于将JSON格式的字符串解析为结构化的数据(即StructType或其他Spark SQL数据类型)。这个函数在处理半结构化数据(如JSON日志、嵌套结构数据)时非常有用。
1. 基本用法
from_json
的主要作用是将JSON字符串解析为指定的Spark SQL数据类型(如StructType、ArrayType等)。通常与schema(模式定义)结合使用,明确解析后数据的结构。
语法
from_json(json_string, schema [, options])
json_string
:要解析的JSON字符串。schema
:定义JSON数据结构的模式,可以是StructType、ArrayType等。options
(可选):用于指定解析选项(如是否允许解析失败、空值处理等)。
2. 数据结构内容(Schema 定义)
from_json
函数需要明确的模式定义(schema),以便将JSON字符串解析为结构化数据。模式可以是以下几种Spark SQL数据类型:
2.1 基本数据类型
StringType
:字符串IntegerType
:整数LongType
:长整型DoubleType
:双精度浮点型BooleanType
:布尔值TimestampType
:时间戳DateType
:日期
2.2 复杂数据类型
StructType
:结构体,类似于JSON对象。ArrayType
:数组,类似于JSON数组。MapType
:键值对,类似于JSON中的键值结构。
3. 使用示例
3.1 示例解析简单JSON
JSON数据:
{"name": "Alice", "age": 25}
SQL实现:
CREATE OR REPLACE TEMP VIEW json_table AS
SELECT '{"name": "Alice", "age": 25}' AS json_string;
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>') AS parsed
FROM json_table;
输出结果:
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
3.2 示例:解析嵌套JSON
JSON数据:
{
"name": "Alice",
"info": {
"age": 25,
"city": "New York"
}
}
SQL实现:
CREATE OR REPLACE TEMP VIEW json_table AS
SELECT '{"name": "Alice", "info": {"age": 25, "city": "New York"}}' AS json_string;
SELECT
from_json(json_string, 'STRUCT<name: STRING, info: STRUCT<age: INT, city: STRING>>') AS parsed
FROM json_table;
输出结果:
+-------------------------+
|parsed |
+-------------------------+
|{Alice, {25, New York}} |
+-------------------------+
3.3 示例:解析JSON数组
JSON数据:
[
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30}
]
SQL实现:
CREATE OR REPLACE TEMP VIEW json_table AS
SELECT '[{"name": "Alice", "age": 25}, {"name": "Bob", "age": 30}]' AS json_string;
SELECT
from_json(json_string, 'ARRAY<STRUCT<name: STRING, age: INT>>') AS parsed
FROM json_table;
输出结果:
+--------------------------+
|parsed |
+--------------------------+
|[{Alice, 25}, {Bob, 30}] |
+--------------------------+
3.4 示例:解析并提取嵌套字段
JSON数据:
{
"name": "Alice",
"info": {
"age": 25,
"city": "New York"
}
}
SQL实现:
CREATE OR REPLACE TEMP VIEW json_table AS
SELECT '{"name": "Alice", "info": {"age": 25, "city": "New York"}}' AS json_string;
SELECT
parsed.name AS name,
parsed.info.age AS age,
parsed.info.city AS city
FROM (
SELECT
from_json(json_string, 'STRUCT<name: STRING, info: STRUCT<age: INT, city: STRING>>') AS parsed
FROM json_table
);
输出结果:
+-------+---+----------+
|name |age|city |
+-------+---+----------+
|Alice |25 |New York |
+-------+---+----------+
4. 常见选项(Options)
以下是from_json
中支持的常见options参数,以及它们的详细说明和使用案例。
4.1 常见 Options 参数
mode
:控制解析模式:PERMISSIVE
、DROPMALFORMED
或FAILFAST
,默认值:PERMISSIVE。columnNameOfCorruptRecord
:如果解析失败,存储错误记录的列名,默认值:空值(无默认值)。timestampFormat
:指定时间戳格式,默认值:yyyy-MM-dd’T’HH:mm:ss.SSSXXX。dateFormat
:指定日期格式,默认值:yyyy-MM-dd。multiLine
:是否允许JSON跨行(即多行JSON),默认值:false。allowUnquotedFieldNames
:是否允许字段名不使用引号,默认值:false。allowSingleQuotes
:是否允许字段名和字符串值使用单引号,默认值:true。allowNumericLeadingZeros
:是否允许数字前置零,默认值:false。allowBackslashEscapingAnyCharacter
:是否允许反斜杠转义任意字符,默认值:false。allowComments
:是否允许JSON中存在注释(如//
或/* */
),默认值:false。
4.2 Options 参数详细解析与案例
4.2.1 mode
mode
用于控制解析模式,支持以下三种模式:
PERMISSIVE
(默认):尝试解析尽可能多的数据。如果某些JSON数据解析失败,Spark会将失败的记录存储在_corrupt_record
列中。DROPMALFORMED
:丢弃所有解析失败的记录。FAILFAST
:如果发现解析错误,则直接抛出异常,停止执行。
案例:mode参数
JSON数据:
{"name": "Alice", "age": 25}
{"name": "Bob", "age": "invalid"}
{"name": "Charlie"}
SQL查询:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('mode', 'PERMISSIVE')) AS parsed
FROM json_table;
输出(PERMISSIVE模式,失败的记录存储在_corrupt_record):
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
|null |
|null |
+----------------+
如果使用DROPMALFORMED
:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('mode', 'DROPMALFORMED')) AS parsed
FROM json_table;
输出(解析失败的记录被丢弃):
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
如果使用FAILFAST
:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('mode', 'FAILFAST')) AS parsed
FROM json_table;
输出:Spark会抛出解析失败的异常。
4.2.2 columnNameOfCorruptRecord
指定存储解析失败记录的列名。如果设置了该选项,解析失败的JSON会存储在指定的列中,而不是默认的_corrupt_record
列。
案例:columnNameOfCorruptRecord
JSON数据:
{"name": "Alice", "age": 25}
{"name": "Bob", "age": "invalid"}
SQL查询:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('columnNameOfCorruptRecord', 'error_record')) AS parsed
FROM json_table;
输出:
+----------------+-------------------+
|parsed |error_record |
+----------------+-------------------+
|{Alice, 25} |null |
|null |{"name": "Bob",...}|
+----------------+-------------------+
4.2.3 timestampFormat 和 dateFormat
用于指定时间戳和日期字段的解析格式。
案例:timestampFormat 和 dateFormat
JSON数据:
{"name": "Alice", "timestamp": "2023-01-01T12:00:00", "birth_date": "1990-01-01"}
SQL查询:
SELECT
from_json(
json_string,
'STRUCT<name: STRING, timestamp: TIMESTAMP, birth_date: DATE>',
map('timestampFormat', 'yyyy-MM-dd\'T\'HH:mm:ss', 'dateFormat', 'yyyy-MM-dd')
) AS parsed
FROM json_table;
输出:
+-------------------------------+
|parsed |
+-------------------------------+
|{Alice, 2023-01-01 12:00:00, 1990-01-01}|
+-------------------------------+
4.2.4 multiLine
指定是否允许JSON数据跨多行。默认值为false。
案例:multiLine
JSON数据:
{
"name": "Alice",
"age": 25
}
SQL查询(multiLine=false,无法解析多行JSON):
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('multiLine', 'false')) AS parsed
FROM json_table;
输出:
+----------------+
|parsed |
+----------------+
|null |
+----------------+
SQL查询(multiLine=true,支持多行JSON):
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('multiLine', 'true')) AS parsed
FROM json_table;
输出:
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
4.2.5 allowUnquotedFieldNames
允许JSON中的字段名不加引号。
案例:allowUnquotedFieldNames
JSON数据:
{name: "Alice", age: 25}
SQL查询:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('allowUnquotedFieldNames', 'true')) AS parsed
FROM json_table;
输出:
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
4.2.6 allowSingleQuotes
允许JSON中的字段名和字符串值使用单引号。
案例:allowSingleQuotes
JSON数据:
{'name': 'Alice', 'age': 25}
SQL查询:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('allowSingleQuotes', 'true')) AS parsed
FROM json_table;
输出:
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
4.2.7 allowComments
允许JSON数据中包含注释(如//
或/* */
)。
案例:allowComments
JSON数据:
{
"name": "Alice", // This is a comment
"age": 25
}
SQL查询:
SELECT
from_json(json_string, 'STRUCT<name: STRING, age: INT>', map('allowComments', 'true')) AS parsed
FROM json_table;
输出:
+----------------+
|parsed |
+----------------+
|{Alice, 25} |
+----------------+
4.3 Options参数总结
from_json
的options参数提供了灵活的JSON解析配置,适用于各种复杂或非标准的JSON数据场景。以下是常用场景的总结:
- 容错性控制:使用
mode
和columnNameOfCorruptRecord
。 - 时间和日期解析:使用
timestampFormat
和dateFormat
。 - 非标准JSON支持:使用
multiLine
、allowUnquotedFieldNames
、allowSingleQuotes
、allowComments
等。
5. from_json
总结
from_json
是Spark SQL中处理JSON数据的核心工具,它的核心是通过指定的schema将JSON字符串解析为结构化数据。通过灵活定义StructType、ArrayType等模式,可以处理简单到复杂的JSON数据结构。如果你有具体的JSON数据或使用场景,可以提供详细信息,我可以进一步帮助你解析和定义适合的schema!
from_json
处理完后,我们对拿到的结果可能还要关联的内容spark sql 对struct、array、map类型的函数操作,这样能更加方便对字符串的解析。