在“数据库”中查询半结构化数据

请注意

在Databricks Runtime 8.1及以上版本中可用。

本文介绍了Databricks SQL操作符,可用于查询和转换存储为JSON的半结构化数据。

请注意

该特性允许您读取半结构化数据,而无需将文件平整化。但是,为了获得最佳的读查询性能,Databricks建议使用正确的数据类型提取嵌套列。

您可以使用以下语法从包含JSON字符串的字段中提取列<列名称>:< extraction-path >,在那里<列名称>字符串是列名和< extraction-path >要提取的字段的路径。返回的结果是字符串。

创建一个包含高度嵌套数据的表

运行以下查询以创建具有高度嵌套数据的表。本文中的示例都引用了这个表。

创建表格store_data作为选择”{“存储”:{“水果”:[{“重量”:8,“类型”:“苹果”},{“重量”:9,“类型”:“梨”}),“篮子”:((1、2、{“b”:“y”,“一个”:“x”}),(3、4),(5、6)),“书”:(奈杰尔•里斯”“作者”:“标题:“世纪名言”,“类别”:“引用”,“价格”:8.95},“作者”:“赫尔曼·麦尔维尔”,“标题”:“白鲸记”,“类别”:“小说”,“价格”:8.99,“isbn”:“0-553-21311-3”},“作者”:“J。r。r。托尔金"“标题”:“指环王”,“类别”:“小说”,“读者”:({“年龄”:25岁的“名称”:“bob”},{“年龄”:26日,“名字”:“杰克”}),“价格”:22.99,“isbn”:“0-395-19395-8”),“自行车”:{“价格”:19.95,“颜色”:“红色”},“老板”:“艾米”,“邮政编码”:“94025”,“fb: testid”:“1234”} '作为

提取顶级列

要提取列,请在提取路径中指定JSON字段的名称。

可以在括号内提供列名。括号内引用的列是匹配的大小写敏感。列名的引用也不区分大小写。

选择老板老板store_data
+-------+-------+|老板|老板|+-------+-------+|艾米|艾米|+-------+-------+
当你使用括号时引用是区分大小写的选择老板case_insensitive:[“主人”case_sensitivestore_data
+------------------+----------------+|case_insensitive|case_sensitive|+------------------+----------------+|艾米||+------------------+----------------+

使用反引号转义空格和特殊字符。字段名以大小写匹配如果不

—使用反引号转义特殊字符。使用反勾号时引用不区分大小写。使用括号区分大小写。选择邮政编码代码邮政编码代码:[“fb: testid”store_data
+----------+----------+-----------+|邮政编码代码|邮政编码代码|神奇动物testid|+----------+----------+-----------+|94025|94025|1234|+----------+----------+-----------+

请注意

如果由于不区分大小写的匹配,JSON记录包含多个可以匹配提取路径的列,那么您将收到一个错误,要求您使用括号。如果行与列之间存在匹配,则不会收到任何错误。以下语句将抛出一个错误:{“foo”:“酒吧”,“Foo”:“酒吧”},下面的语句不会抛出错误:

“foo”“酒吧”“Foo”“酒吧”

提取嵌套字段

通过点表示法或使用括号指定嵌套字段。当您使用方括号时,列是区分大小写匹配的。

使用点表示法选择商店自行车store_data——返回的列是一个字符串
+------------------+|自行车|+------------------+|||“价格”19.95||“颜色”“红色”|||+------------------+
——使用括号选择商店“自行车”),商店“自行车”store_data
+------------------+---------+|自行车|自行车|+------------------+---------+||||“价格”19.95|||“颜色”“红色”|||||+------------------+---------+

从数组中提取值

用括号为数组中的元素建立索引。索引以0为基础。你可以使用星号(),然后用点或括号符号从数组中的所有元素中提取子字段。

——索引元素选择商店水果0),商店水果1store_data
+------------------+-----------------+|水果|水果|+------------------+-----------------+||||“重量”8|“重量”9||“类型”“苹果”|“类型”“梨”||||+------------------+-----------------+
——从数组中提取子字段选择商店].国际标准图书编号store_data
+--------------------+|国际标准图书编号|+--------------------+|||||“0-553-21311-3”||“0-395-19395-8”|||+--------------------+
——访问数组中的数组或数组中的结构选择商店篮子),商店篮子] [0first_of_baskets商店篮子0] [first_basket商店篮子] [all_elements_flattened商店篮子0] [2].b子域store_data
+----------------------------+------------------+---------------------+---------------------------------+----------+|篮子|first_of_baskets|first_basket|all_elements_flattened|子域|+----------------------------+------------------+---------------------+---------------------------------+----------+||||12, {“b”“y”“一个”“x”},3.456|y||12, {“b”“y”“一个”“x”}),|1|1||||3.4),|3.|2||||56|5|“b”“y”“一个”“x”|||||||||+----------------------------+------------------+---------------------+---------------------------------+----------+

把值

你可以使用::将值转换为基本数据类型。使用from_json方法将嵌套结果强制转换为更复杂的数据类型,如数组或结构。

——price返回double类型,而不是string类型选择商店自行车价格::store_data
+------------------+|价格|+------------------+|19.95|+------------------+
——使用from_json转换为更复杂的类型选择from_json商店自行车'价格双倍,颜色字符串'自行车store_data——返回的列是一个包含列price和color的结构体
+------------------+|自行车|+------------------+|||“价格”19.95||“颜色”“红色”|||+------------------+
选择from_json商店篮子),“数组<数组<字符串> >”篮子store_data——返回的列是字符串数组的数组
+------------------------------------------+|篮子|+------------------------------------------+|||“1”“2”“{\”b\”\”y\”\”一个\”\”x\”}]”||“3”“4”),||“5”“6”|||+------------------------------------------+

空的行为

的JSON字段存在时值,您将收到一个SQL值,而不是文本值。

选择”{零}“关键”:“关键sql_null”{零}“关键”:“关键= =“零”text_null
+-------------+-----------+|sql_null|text_null|+-------------+-----------+|真正的||+-------------+-----------+

使用Spark SQL操作符转换嵌套数据

Apache Spark有许多用于处理复杂和嵌套数据的内置函数。下面的笔记本包含了一些例子。

此外,高阶函数当内置Spark操作符不能以您想要的方式转换数据时,提供许多额外的选项。

复杂嵌套数据笔记本

在新标签页打开笔记本