查询嵌套数据
如果您使用 flatten_arrays=FALSE
(默认)加载 JSON 或 Avro 数据,则 __raw__
列中的 VMap 数据可以包含多个嵌套结构。事实上,任何 VMap JSON 或 Avro 数据都可以包含嵌套结构。此部分描述如何以最好方式查询此类数据。
查询 VMap 嵌套值
要查询嵌套结构,您可以使用多个 maplookup()
函数,每个级别一个。但是,最有效的方法是使用括号 ([]
) 运算符。
解析或提取 VMap 数据时,默认行为是修整数据。修整的 VMap 数据将键名连接成一个长名称,使用默认分隔符 (.
) 或用户定义的分隔符分隔元素。
要对 VMap 数据中的嵌套结构使用括号运算符,数据不能被修整。此外,您不能对任何现有的修整 VMap 数据使用括号运算符。
要正确加载或提取 VMap 数据,请为 fjsonparser
、favroparser
和 mapjsonextractor()
函数指定 flatten_maps=FALSE
。
注意
虽然括号运算符值看起来类似于数组元素规范,但它们是字符串,而不是整数。您必须将每个嵌套结构作为字符串输入,即使值是整数。例如,如果值为 2,请将其指定为['2']
,而不是 [2]
。
嵌套 JSON 的括号运算符
此示例使用以下 JSON 数据作为嵌套数据的示例。将此数据另存为 restaurant.json
:
{
"restaurant" : {
"_name_" : "Bob's pizzeria",
"cuisine" : "Italian",
"location" : {"city" : "Cambridge", "zip" : "02140"},
"menu" : [{"item" : "cheese pizza", "price" : "$8.25"},
{"item" : "chicken pizza", "price" : "$11.99"},
{"item" : "spinach pizza", "price" : "$10.50"}]
}
}
创建 Flex 表 rests,并使用 restaurant.json 文件加载它:
=> COPY rests FROM '/home/dbadmin/tempdat/restaurant.json' PARSER fjsonparser (flatten_maps=false);
Rows Loaded
-------------
1
(1 row)
将数据加载到 Flex 表后,有两种方法可以使用括号访问嵌套数据:
-
从
__raw__
列开始,后跟括号中的字符值 -
从最顶层元素的名称开始,后跟括号中的字符值
两种方法同样有效。以下是两者的示例:
=> SELECT __raw__['restaurant']['location']['city'] FROM rests;
__raw__
-----------
Cambridge
(1 row)
=> SELECT restaurant['location']['city'] from rests;
restaurant
------------
Cambridge
(1 row)
推特数据的括号运算符
此示例展示如何从推特数据中提取一些基本信息。
创建 Flex 表 tweets
并加载一些数据后,Flex 表有一个推文块。
在下面的 SELECT
语句中,注意如何指定表 tweets
的 __raw__
列(后跟括号运算符)来定义相关虚拟列 (['delete']['status']['user_id']
)。此查询使用 COUNT()
函数计算已删除推文的数量并输出 10 个结果:
=> SELECT __raw__['delete']['status']['user_id'] as UserId, COUNT(*) as TweetsDelete from tweets
-> WHERE mapcontainskey(__raw__, 'delete')
-> GROUP BY __raw__['delete']['status']['user_id']
-> ORDER BY TweetsDelete DESC, UserID ASC LIMIT 10;
UserId | TweetsDelete
-----------+--------------
106079547 | 4
403474369 | 4
181188657 | 3
223136123 | 3
770139481 | 3
154602299 | 2
192127653 | 2
215011332 | 2
23321883 | 2
242173898 | 2
(10 rows)