Azure Synapse Analytics のサーバーレス SQL プールを使用して Parquet および JSON ファイルで入れ子にされた型に対してクエリを実行する
この記事では、Azure Synapse Analytics のサーバーレス SQL プールを使用してクエリを作成する方法について説明します。 このクエリでは、Parquet の入れ子にされた型が読み取られます。 入れ子になった型は、オブジェクトまたは配列を表す複雑な構造体です。 入れ子になった型は、次のように格納できます。
- Parquet: 配列とオブジェクトを含む複数の複合列を格納できます。
- 階層型の JSON ファイル: 複雑な JSON ドキュメントを 1 つの列として読み取ることができます。
- Azure Cosmos DB コレクション (現在はゲート付きパブリック プレビュー): すべてのドキュメントに複雑な入れ子になったプロパティを含めることができます。
サーバーレス SQL プールでは、入れ子にされたすべての型が JSON オブジェクトと配列として書式設定されます。 そのため、JSON 関数を使用して複雑なオブジェクトを抽出または変更することも、OPENJSON 関数を使用して JSON データを解析することもできます。
次に、入れ子になったオブジェクトを含む JSON ファイル COVID-19 Open Research Dataset からスカラー値とオブジェクト値を抽出するクエリの例を示します。
SELECT
title = JSON_VALUE(doc, '$.metadata.title'),
first_author = JSON_QUERY(doc, '$.metadata.authors[0]'),
first_author_name = JSON_VALUE(doc, '$.metadata.authors[0].first'),
complex_object = doc
FROM
OPENROWSET(
BULK 'https://azureopendatastorage.blob.core.windows.net/covid19temp/comm_use_subset/pdf_json/000b7d1517ceebb34e1e3e817695b6de03e2fa78.json',
FORMAT='CSV', FIELDTERMINATOR ='0x0b', FIELDQUOTE = '0x0b', ROWTERMINATOR = '0x0b'
)
WITH ( doc varchar(MAX) ) AS docs;
JSON_VALUE
関数によって、指定されたパスのフィールドからスカラー値が返されます。 JSON_QUERY
関数によって、指定されたパスのフィールドから JSON として書式設定されたオブジェクトが返されます。
重要
この例では COVID-19 Open Research Dataset のファイルを使用します。 ライセンスとデータの構造は、こちらを参照してください。
前提条件
最初の手順では、データソースが作成されるデータベースを作成します。 次に、そのデータベースでセットアップ スクリプトを実行して、オブジェクトを初期化します。 このセットアップ スクリプトにより、サンプルで使用されるデータ ソース、データベース スコープの資格情報、および外部ファイル形式が作成されます。
入れ子にされたデータまたは繰り返しのデータを射影する
Parquet ファイルには、複合型を持つ複数の列を含めることができます。 これらの列の値は、JSON テキストとして書式設定され、VARCHAR 列として返されます。 次のクエリでは、structExample.parquet ファイルが読み取られ、入れ子にされた列の値を読み取る方法が示されます。
SELECT
DateStruct, TimeStruct, TimestampStruct, DecimalStruct, FloatStruct
FROM
OPENROWSET(
BULK 'parquet/nested/structExample.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
)
WITH (
DateStruct VARCHAR(8000),
TimeStruct VARCHAR(8000),
TimestampStruct VARCHAR(8000),
DecimalStruct VARCHAR(8000),
FloatStruct VARCHAR(8000)
) AS [r];
このクエリでは、次の結果が返されます。 すべての入れ子になったオブジェクトの内容が JSON テキストとして返されます。
DateStruct | TimeStruct | TimestampStruct | DecimalStruct | FloatStruct |
---|---|---|---|---|
{"Date":"2009-04-25"} | {"Time":"20:51:54.3598000"} | {"Timestamp":"5501-04-08 12:13:57.4821000"} | {"Decimal":11143412.25350} | {"Float":0.5} |
{"Date":"1916-04-29"} | {"Time":"00:16:04.6778000"} | {"Timestamp":"1990-06-30 20:50:52.6828000"} | {"Decimal":1963545.62800} | {"Float":-2.125} |
次のクエリでは、justSimpleArray.parquet ファイルが読み取られます。 Parquet ファイルから、入れ子にされたデータと繰り返しデータを含むすべての列が射影されます。
SELECT
SimpleArray
FROM
OPENROWSET(
BULK 'parquet/nested/justSimpleArray.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
) AS [r];
クエリでは、次の結果が返されます。
SimpleArray |
---|
[11,12,13] |
[21,22,23] |
入れ子になったオブジェクト列からプロパティを読み取る
JSON_VALUE
関数を使用すると、JSON テキストとして書式設定された列から値を返すことができます。
SELECT
title = JSON_VALUE(complex_column, '$.metadata.title'),
first_author_name = JSON_VALUE(complex_column, '$.metadata.authors[0].first'),
body_text = JSON_VALUE(complex_column, '$.body_text.text'),
complex_column
FROM
OPENROWSET( BULK 'https://azureopendatastorage.blob.core.windows.net/covid19temp/comm_use_subset/pdf_json/000b7d1517ceebb34e1e3e817695b6de03e2fa78.json',
FORMAT='CSV', FIELDTERMINATOR ='0x0b', FIELDQUOTE = '0x0b', ROWTERMINATOR = '0x0b' ) WITH ( complex_column varchar(MAX) ) AS docs;
結果を次の表に示します。
title | first_author_name | body_text | complex_column |
---|---|---|---|
Supplementary Information An eco-epidemiolo... | Julien | - Figure S1 :Phylogeny of... | { "paper_id": "000b7d1517ceebb34e1e3e817695b6de03e2fa78", "metadata": { "title": "Supplementary Information An eco-epidemiological study of Morbilli-related paramyxovirus infection in Madagascar bats reveals host-switching as the dominant macro-evolutionary mechanism", "authors": [ { "first": "Julien" |
JSON ファイルとは異なり、ほとんどの場合、複雑な JSON オブジェクトを含む 1 つの列が返されますが、Parquet ファイルには複数の複合列を含めることができます。 各列で JSON_VALUE
関数を使用して、入れ子になった列のプロパティを読み取ることができます。 OPENROWSET
を使用すると、WITH
句で入れ子になったプロパティのパスを直接指定できます。 パスを列の名前として設定することも、列の型の後に JSON パス式を追加することもできます。
次のクエリでは、structExample.parquet ファイルが読み取られ、入れ子にされた列の要素の表示方法が示されます。 入れ子にされた値を参照するには、次の 2 つの方法があります。
- 型の指定の後に、入れ子にされた値のパス式を指定する。
- "." を使用して、列名を入れ子にされたパスとして書式設定し、フィールドを参照する。
SELECT
*
FROM
OPENROWSET(
BULK 'parquet/nested/structExample.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
)
WITH (
[DateValue] DATE '$.DateStruct.Date',
[TimeStruct.Time] TIME,
[TimestampStruct.Timestamp] DATETIME2,
DecimalValue DECIMAL(18, 5) '$.DecimalStruct.Decimal',
[FloatStruct.Float] FLOAT
) AS [r];
繰り返される列から要素にアクセスする
次のクエリでは、justSimpleArray.parquet ファイルを読み取り、JSON_VALUE を使用して、配列やマップなど、繰り返される列内からスカラー要素を取得します。
SELECT
*,
JSON_VALUE(SimpleArray, '$[0]') AS FirstElement,
JSON_VALUE(SimpleArray, '$[1]') AS SecondElement,
JSON_VALUE(SimpleArray, '$[2]') AS ThirdElement
FROM
OPENROWSET(
BULK 'parquet/nested/justSimpleArray.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
) AS [r];
結果は次のとおりです。
SimpleArray | FirstElement | SecondElement | ThirdElement |
---|---|---|---|
[11,12,13] | 11 | 12 | 13 |
[21,22,23] | 21 | 22 | 23 |
複合列からサブオブジェクトにアクセスする
次のクエリでは、mapExample.parquet ファイルを読み取り、JSON_QUERY を使用して、配列やマップなど、繰り返される列内から非スカラー要素を取得します。
SELECT
MapOfPersons,
JSON_QUERY(MapOfPersons, '$."John Doe"') AS [John]
FROM
OPENROWSET(
BULK 'parquet/nested/mapExample.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
) AS [r];
返す列を WITH
句で明示的に参照することもできます。
SELECT DocId,
MapOfPersons,
JSON_QUERY(MapOfPersons, '$."John Doe"') AS [John]
FROM
OPENROWSET(
BULK 'parquet/nested/mapExample.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
)
WITH (DocId bigint, MapOfPersons VARCHAR(max)) AS [r];
構造 MapOfPersons
は VARCHAR 列として返され、JSON 文字列としてフォーマットされます。
繰り返される列から値を射影する
一部の列にスカラー値の配列 ([1,2,3]
など) がある場合は、次のスクリプトを使用して、それらを簡単に展開し、メインの行と結合することができます。
SELECT
SimpleArray, Element
FROM
OPENROWSET(
BULK 'parquet/nested/justSimpleArray.parquet',
DATA_SOURCE = 'SqlOnDemandDemo',
FORMAT='PARQUET'
) AS arrays
CROSS APPLY OPENJSON (SimpleArray) WITH (Element int '$') as array_values
次のステップ
次の記事では、JSON ファイルに対してクエリを実行する方法について説明します。