FJSONPARSER
解析并加载 JSON 文件。此文件可能包含重复的 JSON 数据对象(包括嵌套映射)或 JSON 元素的外部列表。
加载到 Flex 表或混合表中时,解析器将 JSON 数据存储在单值 VMap 中。加载到混合表或列式表中时,解析器将数据直接加载到列名称与 JSON 源数据键相匹配的任何表列。
您可以使用强类型加载 JSON 源(数组、结构或组合)中的复杂类型,或将其作为灵活的复杂类型加载。将灵活的复杂类型加载到 VMap 列中的操作与加载到 Flex 表中一样。要加载复杂类型作为 VMap 列,请将列类型指定为 LONG VARBINARY。要保留复杂类型的索引,请将 flatten_maps
设置为 false。
仅当指定了 record_terminator
时,FJSONPARSER 才支持 协作解析。它不支持分摊加载。
语法
FJSONPARSER ( [parameter=value[,...]] )
参数
flatten_maps
- 布尔值,是否将 JSON 数据中的子映射平展,以句点 (
.
) 分隔映射层级。此值会影响加载中的所有数据,包括嵌套映射。此参数仅适用于 Flex 表或 VMap 列,且会在加载强类型复杂类型时被忽略。
默认值:true
flatten_arrays
- 布尔值,是否将列表转换为带有整数键的子映射。列表被平展后,键名会像映射一样连接起来。默认不对列表进行平展。此值影响加载中的所有数据,包括嵌套列表。
此参数仅适用于 Flex 表或 VMap 列,且会在加载强类型复杂类型时被忽略。
默认值:false
reject_on_duplicate
- 布尔值,是忽略重复记录 (false),还是拒绝重复记录 (true)。在任何一种情况下,都会继续加载。
默认值:false
reject_on_empty_key
- 布尔值,是否拒绝包含的字段键不含值的任何行。
默认值:false
omit_empty_keys
- 布尔值,是否忽略数据中不含值的任何字段键。同一记录中的其他字段将加载。
默认值:false
record_terminator
- 设置后,将跳过所有无效的 JSON 记录,并继续解析下一个记录。必须统一终止记录。例如,如果您的输入文件包含通过换行符终止的 JSON 记录,请将此参数设置为
E'\n')
。如果存在任何无效的 JSON 记录,则在下一个record_terminator
之后继续解析。即使数据不包含无效的记录,也可以指定显式记录终止符,这样可以提高协作解析和分摊加载的运行效率,从而提升加载性能。
如果忽略此参数,解析将在第一条无效 JSON 记录处结束。
reject_on_materialized_type_error
布尔值,是否拒绝包含无法强制转换为兼容数据类型的实体化列值的数据行。如果值为 false 且无法强制类型,则解析器将该列中的值设置为 null。
如果该列是强类型复杂类型,而不是可变复杂类型,则复杂类型中的类型不匹配将导致整个列被视为不匹配。解析器不会部分加载复杂类型。
默认值:false
start_point
- 字符串,即 JSON 加载数据中用作解析起点的键的名称。解析器忽略
start_point
值之前的所有数据。将为文件中的每个对象加载该值。解析器会处理第一个实例后面的数据,最多到第二个,便会忽略任何保留的数据。 start_point_occurrence
- 整数,您通过
start_point
指定的值的第 n 次出现。如果数据具有多个起始值,而且您知道要在其第几次出现时开始解析,请与start_point
结合使用。默认值: 1
suppress_nonalphanumeric_key_chars
- 布尔值,是否禁止显示 JSON 键值中的非字母数字字符。当此参数为 true 时,解析器将用下划线 (
_
) 替换这些字符。默认值:false
key_separator
- 解析器在连接键名时要使用的字符。
默认: 句点 (
.
)
示例
以下示例使用默认参数从 STDIN 加载 JSON 数据:
=> CREATE TABLE people(age INT, name VARCHAR);
CREATE TABLE
=> COPY people FROM STDIN PARSER FJSONPARSER();
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> {"age": 5, "name": "Tim"}
>> {"age": 3}
>> {"name": "Fred"}
>> {"name": "Bob", "age": 10}
>> \.
=> SELECT * FROM people;
age | name
-----+------
| Fred
10 | Bob
5 | Tim
3 |
(4 rows)
以下示例使用 reject_on_duplicate
参数拒绝重复值:
=> CREATE FLEX TABLE json_dupes();
CREATE TABLE
=> COPY json_dupes FROM stdin PARSER fjsonparser(reject_on_duplicate=true)
exceptions '/home/dbadmin/load_errors/json_e.out'
rejected data '/home/dbadmin/load_errors/json_r.out';
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself.
>> {"a":"1","a":"2","b":"3"}
>> \.
=> \!cat /home/dbadmin/load_errors/json_e.out
COPY: Input record 1 has been rejected (Rejected by user-defined parser).
Please see /home/dbadmin/load_errors/json_r.out, record 1 for the rejected record.
COPY: Loaded 0 rows, rejected 1 rows.
以下示例将加载数组数据:
$ cat addrs.json
{"number": 301, "street": "Grant", "attributes": [1, 2, 3, 4]}
=> CREATE EXTERNAL TABLE customers(number INT, street VARCHAR, attributes ARRAY[INT])
AS COPY FROM 'addrs.json' PARSER fjsonparser();
=> SELECT number, street, attributes FROM customers;
num | street| attributes
-----+-----------+---------------
301 | Grant | [1,2,3,4]
(1 row)
以下示例将加载一个灵活的复杂类型,同时拒绝嵌套记录中具有空键的行。请注意,虽然数据包含两家餐厅,但其中一家的键名是空字符串。此餐厅将被拒绝:
$ cat rest1.json
{
"name" : "Bob's pizzeria",
"cuisine" : "Italian",
"location_city" : ["Cambridge", "Pittsburgh"],
"menu" : [{"item" : "cheese pizza", "" : "$8.25"},
{"item" : "spinach pizza", "price" : "$10.50"}]
}
{
"name" : "Bakersfield Tacos",
"cuisine" : "Mexican",
"location_city" : ["Pittsburgh"],
"menu" : [{"item" : "veggie taco", "price" : "$9.95"},
{"item" : "steak taco", "price" : "$10.95"}]
}
=> CREATE TABLE rest (name VARCHAR, cuisine VARCHAR, location_city LONG VARBINARY, menu LONG VARBINARY);
=> COPY rest FROM '/data/rest1.json'
PARSER fjsonparser(flatten_maps=false, reject_on_empty_key=true);
Rows Loaded
------------
1
(1 row)
=> SELECT maptostring(location_city), maptostring(menu) FROM rest;
maptostring | maptostring
---------------------------+-------------------------------------------------------
{
"0": "Pittsburgh"
} | {
"0": {
"item": "veggie taco",
"price": "$9.95"
},
"1": {
"item": "steak taco",
"price": "$10.95"
}
}
(1 row)
要改为加载部分数据,请使用 omit_empty_keys
在加载其他所有内容时绕过缺失键:
=> COPY rest FROM '/data/rest1.json'
PARSER fjsonparser(flatten_maps=false, omit_empty_keys=true);
Rows Loaded
-------------
2
(1 row)
=> SELECT maptostring(location_city), maptostring(menu) from rest;
maptostring | maptostring
-------------------------------------------------+---------------------------------
{
"0": "Pittsburgh"
} | {
"0": {
"item": "veggie taco",
"price": "$9.95"
},
"1": {
"item": "steak taco",
"price": "$10.95"
}
}
{
"0": "Cambridge",
"1": "Pittsburgh"
} | {
"0": {
"item": "cheese pizza"
},
"1": {
"item": "spinach pizza",
"price": "$10.50"
}
}
(2 rows)
要改为使用强类型加载此数据,请在表中定义复杂类型:
=> CREATE EXTERNAL TABLE restaurants
(name VARCHAR, cuisine VARCHAR,
location_city ARRAY[VARCHAR(80)],
menu ARRAY[ ROW(item VARCHAR(80), price FLOAT) ]
)
AS COPY FROM '/data/rest.json' PARSER fjsonparser();
=> SELECT * FROM restaurants;
name | cuisine | location_city | \
menu
-------------------+---------+----------------------------+--------------------\
--------------------------------------------------------
Bob's pizzeria | Italian | ["Cambridge","Pittsburgh"] | [{"item":"cheese pi\
zza","price":0.0},{"item":"spinach pizza","price":0.0}]
Bakersfield Tacos | Mexican | ["Pittsburgh"] | [{"item":"veggie ta\
co","price":0.0},{"item":"steak taco","price":0.0}]
(2 rows)
有关其他示例,请参阅 JSON 数据。