メインコンテンツまでスキップ

JSON 文字列のクエリ

この記事では、JSON 文字列として格納された半構造化データのクエリと変換に使用できる Databricks SQL 演算子について説明します。

注記

この機能を使用すると、ファイルをフラット化せずに半構造化データを読み取ることができます。 ただし、最適な読み取りクエリ パフォーマンスを得るために、Databricks では、正しいデータ型で入れ子になった列を抽出することをお勧めします。

JSON文字列を含むフィールドから列を抽出するには、構文 (<column-name>:<extraction-path> <column-name> は文字列の列名、<extraction-path> は抽出するフィールドへのパスです)。返される結果は文字列です。

高度にネストされたデータを含むテーブルを作成する

次のクエリを実行して、高度にネストされたデータを含むテーブルを作成します。 この記事の例はすべて、このテーブルを参照しています。

SQL
CREATE TABLE store_data AS SELECT
'{
"store":{
"fruit": [
{"weight":8,"type":"apple"},
{"weight":9,"type":"pear"}
],
"basket":[
[1,2,{"b":"y","a":"x"}],
[3,4],
[5,6]
],
"book":[
{
"author":"Nigel Rees",
"title":"Sayings of the Century",
"category":"reference",
"price":8.95
},
{
"author":"Herman Melville",
"title":"Moby Dick",
"category":"fiction",
"price":8.99,
"isbn":"0-553-21311-3"
},
{
"author":"J. R. R. Tolkien",
"title":"The Lord of the Rings",
"category":"fiction",
"reader":[
{"age":25,"name":"bob"},
{"age":26,"name":"jack"}
],
"price":22.99,
"isbn":"0-395-19395-8"
}
],
"bicycle":{
"price":19.95,
"color":"red"
}
},
"owner":"amy",
"zip code":"94025",
"fb:testid":"1234"
}' as raw

最上位の列を抽出します

列を抽出するには、抽出パスで JSON フィールドの名前を指定します。

列名を角かっこで囲むことができます。 角かっこ内で参照される列は次のとおりです 大文字と小文字 が区別されます 。 列名も大文字と小文字を区別せずに参照されます。

SQL
SELECT raw:owner, RAW:owner FROM store_data
+-------+-------+
| owner | owner |
+-------+-------+
| amy | amy |
+-------+-------+
SQL
-- References are case sensitive when you use brackets
SELECT raw:OWNER case_insensitive, raw:['OWNER'] case_sensitive FROM store_data
+------------------+----------------+
| case_insensitive | case_sensitive |
+------------------+----------------+
| amy | null |
+------------------+----------------+

バッククォートを使用して、スペースや特殊文字をエスケープします。 フィールド名は大文字と小文字 を区別せずに 一致します。

SQL
-- Use backticks to escape special characters. References are case insensitive when you use backticks.
-- Use brackets to make them case sensitive.
SELECT raw:`zip code`, raw:`Zip Code`, raw:['fb:testid'] FROM store_data
+----------+----------+-----------+
| zip code | Zip Code | fb:testid |
+----------+----------+-----------+
| 94025 | 94025 | 1234 |
+----------+----------+-----------+
注記

大文字と小文字を区別しない一致により、抽出パスに一致する可能性のある複数の列が JSON レコードに含まれている場合、角括弧を使用するように求めるエラーが表示されます。 行間で列が一致している場合、エラーは発生しません。 次の例はエラーをスローします: {"foo":"bar", "Foo":"bar"}、次の文字列はエラーをスローしません。

{"foo":"bar"}
{"Foo":"bar"}

ネストされたフィールドの抽出

ネストされたフィールドは、ドット表記または括弧を使用して指定します。 角かっこを使用すると、列は大文字と小文字が区別されて一致します。

SQL
-- Use dot notation
SELECT raw:store.bicycle FROM store_data
-- the column returned is a string
+------------------+
| bicycle |
+------------------+
| { |
| "price":19.95, |
| "color":"red" |
| } |
+------------------+
SQL
-- Use brackets
SELECT raw:store['bicycle'], raw:store['BICYCLE'] FROM store_data
+------------------+---------+
| bicycle | BICYCLE |
+------------------+---------+
| { | null |
| "price":19.95, | |
| "color":"red" | |
| } | |
+------------------+---------+

配列から値を抽出する

配列内の要素には角括弧でインデックスを付けます。 インデックスは 0 から始まります。 アスタリスク (*) の後にドットまたは角括弧の表記を使用して、配列内のすべての要素からサブフィールドを抽出できます。

SQL
-- Index elements
SELECT raw:store.fruit[0], raw:store.fruit[1] FROM store_data
+------------------+-----------------+
| fruit | fruit |
+------------------+-----------------+
| { | { |
| "weight":8, | "weight":9, |
| "type":"apple" | "type":"pear" |
| } | } |
+------------------+-----------------+
SQL
-- Extract subfields from arrays
SELECT raw:store.book[*].isbn FROM store_data
+--------------------+
| isbn |
+--------------------+
| [ |
| null, |
| "0-553-21311-3", |
| "0-395-19395-8" |
| ] |
+--------------------+
SQL
-- Access arrays within arrays or structs within arrays
SELECT
raw:store.basket[*],
raw:store.basket[*][0] first_of_baskets,
raw:store.basket[0][*] first_basket,
raw:store.basket[*][*] all_elements_flattened,
raw:store.basket[0][2].b subfield
FROM store_data
+----------------------------+------------------+---------------------+---------------------------------+----------+
| basket | first_of_baskets | first_basket | all_elements_flattened | subfield |
+----------------------------+------------------+---------------------+---------------------------------+----------+
| [ | [ | [ | [1,2,{"b":"y","a":"x"},3,4,5,6] | y |
| [1,2,{"b":"y","a":"x"}], | 1, | 1, | | |
| [3,4], | 3, | 2, | | |
| [5,6] | 5 | {"b":"y","a":"x"} | | |
| ] | ] | ] | | |
+----------------------------+------------------+---------------------+---------------------------------+----------+

キャストバリュー

:: を使用して、値を基本データ型にキャストできます。from_jsonメソッドを使用して、ネストされた結果を配列や構造体などのより複雑なデータ型にキャストします。

SQL
-- price is returned as a double, not a string
SELECT raw:store.bicycle.price::double FROM store_data
+------------------+
| price |
+------------------+
| 19.95 |
+------------------+
SQL
-- use from_json to cast into more complex types
SELECT from_json(raw:store.bicycle, 'price double, color string') bicycle FROM store_data
-- the column returned is a struct containing the columns price and color
+------------------+
| bicycle |
+------------------+
| { |
| "price":19.95, |
| "color":"red" |
| } |
+------------------+
SQL
SELECT from_json(raw:store.basket[*], 'array<array<string>>') baskets FROM store_data
-- the column returned is an array of string arrays
+------------------------------------------+
| basket |
+------------------------------------------+
| [ |
| ["1","2","{\"b\":\"y\",\"a\":\"x\"}]", |
| ["3","4"], |
| ["5","6"] |
| ] |
+------------------------------------------+

NULL の動作

null値を持つ JSON フィールドが存在する場合、その列の SQL null 値は、nullテキスト値ではなく、受け取ります。

SQL
select '{"key":null}':key is null sql_null, '{"key":null}':key == 'null' text_null
+-------------+-----------+
| sql_null | text_null |
+-------------+-----------+
| true | null |
+-------------+-----------+

Spark SQL 演算子を使用したネストされたデータの変換

Apache Spark には、複雑なデータやネストされたデータを操作するための組み込み関数が多数あります。 次のノートブックには例が含まれています。

さらに、 高階関数 には、組み込みの Spark 演算子を使用してデータを必要な方法で変換できない場合に、多くの追加オプションが用意されています。

複雑な入れ子になったデータ ノートブック

Open notebook in new tab