AWS Glue
開発者ガイド

カスタム分類子の書き込み

AWS Glue で grok パターンまたは XML タグを使用して、データを分類するためのカスタム分類子を提供できます。クローラがカスタム分類子を呼び出します。分類子がデータを認識すると、データの分類とスキーマがクローラに返されます。組み込みの分類子にデータが一致しない場合、または、クローラにより作成されたテーブルをカスタマイズする場合は、カスタム分類子を定義する必要があるかもしれません。

AWS Glue コンソールを使用して分類子を作成する方法の詳細については、「AWS Glue コンソールでの分類子の操作」を参照してください。

AWS Glue は、組み込みの分類子の前に、指定した順序でカスタム分類子を実行します。クローラがデータに一致する分類子を検出すると、分類の文字列とスキーマが AWS Glue データカタログ に書き込まれるテーブルの定義で使用されます。

Grok カスタム分類子の書き込み

Grok は、一致するパターンによりテキストデータを解析するために使用するツールです。grok パターンは名前のついた一連の正規表現 (regex) で、一度に 1 行のデータごとに一致させるために使用されます。AWS Glue​ は grok パターンを使用してデータのスキーマを推測します。grok パターンがデータと一致すると、AWS Glue はそのパターンを使用してデータの構造を判断し、フィールドにマッピングします。

AWS Glue は数多くの組み込みパターンを提供します。または、独自のパターンを定義することもできます。組み込みパターンとカスタム分類子の定義にあるカスタムパターンを使用して grok パターンを作成できます。grok パターンをカスタマイズしてカスタムテキストファイル形式を分類できます。

注記

AWS Glue grok カスタム分類子は、 で作成されたテーブルの シリアル化ライブラリを使用します。、、または で を使用している場合、それらのサービスのドキュメントで GrokSerDe のサポートに関する情報を確認してください。現在、 と の を使用して作成されたテーブルのクエリを実行する際に問題が発生することがあります。

grok パターンのコンポーネントの基本的な構文を以下に示します。

%{PATTERN:field-name}

名付けられた PATTERN に一致するデータは、スキーマの field-name 列にデフォルトのデータ型 string でマッピングされます。必要に応じて、フィールドのデータ型は結果のスキーマの bytebooleandoubleshortintlong、または float にキャストできます。

%{PATTERN:field-name:data-type}

たとえば、num フィールドを int データ型にキャストするには、以下のパターンを使用することができます。

%{NUMBER:num:int}

パターンは他のパターンで構成できます。たとえば、SYSLOG タイムスタンプのパターンを月、日、時間のパターン (Feb 1 06:25:43 など) で定義できます。このデータの場合、次のパターンを定義できます。

SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}

注記

grok パターンは、一度に 1 行ずつしか処理できません。複数行のパターンはサポートされていません。また、パターン内の改行はサポートされていません。

AWS Glue のカスタム分類子の値

grok 分類子を定義する場合、AWS Glue に以下の値を指定しカスタム分類子を作成します。

名前

分類子の名前。

分類

分類されたデータの形式を説明するために記述されたテキスト文字列 (例: special-logs)。

Grok パターン

データストアに適用される一連のパターンで、一致があるかどうかを決定します。これらのパターンは AWS Glue の組み込みパターンと定義されたカスタムパターンによるものです。

grok パターンのシンプルな例を次に示します。

%{TIMESTAMP_ISO8601:timestamp} \[%{MESSAGEPREFIX:message_prefix}\] %{CRAWLERLOGLEVEL:loglevel} : %{GREEDYDATA:message}

データが TIMESTAMP_ISO8601 と一致すると、スキーマの列 timestamp が作成されます。動作は、例にある他の名前付きパターンに似ています。

カスタムパターン

独自に定義するオプションのカスタムパターン。これらのパターンは、データを分類する grok パターンにより参照されます。データに適用される grok パターンでこれらのカスタムパターンを参照できます。各カスタムコンポーネントパターンは別々の行にある必要があります。 正規表現 (regex) 構文は、パターンを定義するために使用されます。

以下は、カスタムパターンを使用する例です。

CRAWLERLOGLEVEL (BENCHMARK|ERROR|WARN|INFO|TRACE) MESSAGEPREFIX .*-.*-.*-.*-.*

最初の名前付きカスタムパターンである CRAWLERLOGLEVEL は、列挙された文字列の 1 つとデータが一致するときに一致となります。2 番目のカスタムパターン MESSAGEPREFIX は、メッセージのプレフィックス文字列との一致を試みます。

AWS Glue は、作成日時、最終更新時間、分類子のバージョンを追跡します。

AWS Glue 組み込みパターン

AWS Glue は、カスタム分類子を構築するために使用できる多くの一般的なパターンを提供します。分類子の定義の grok pattern に名前付きパターンを追加します。

次のリストは、各パターンの行です。各行で、パターン名の後に定義があります。 正規表現 (regex) 構文は、パターンを定義するために使用されます。

#AWS Glue Built-in patterns USERNAME [a-zA-Z0-9._-]+ USER %{USERNAME:UNWANTED} INT (?:[+-]?(?:[0-9]+)) BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+))) NUMBER (?:%{BASE10NUM:UNWANTED}) BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+)) BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b BOOLEAN (?i)(true|false) POSINT \b(?:[1-9][0-9]*)\b NONNEGINT \b(?:[0-9]+)\b WORD \b\w+\b NOTSPACE \S+ SPACE \s* DATA .*? GREEDYDATA .* #QUOTEDSTRING (?:(?<!\\)(?:"(?:\\.|[^\\"])*"|(?:'(?:\\.|[^\\'])*')|(?:`(?:\\.|[^\\`])*`))) QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``)) UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12} # Networking MAC (?:%{CISCOMAC:UNWANTED}|%{WINDOWSMAC:UNWANTED}|%{COMMONMAC:UNWANTED}) CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4}) WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2}) COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2}) IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)? IPV4 (?<![0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9]) IP (?:%{IPV6:UNWANTED}|%{IPV4:UNWANTED}) HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-_]{0,62}))*(\.?|\b) HOST %{HOSTNAME:UNWANTED} IPORHOST (?:%{HOSTNAME:UNWANTED}|%{IP:UNWANTED}) HOSTPORT (?:%{IPORHOST}:%{POSINT:PORT}) # paths PATH (?:%{UNIXPATH}|%{WINPATH}) UNIXPATH (?>/(?>[\w_%!$@:.,~-]+|\\.)*)+ #UNIXPATH (?<![\w\/])(?:/[^\/\s?*]*)+ TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+)) WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+ URIPROTO [A-Za-z]+(\+[A-Za-z+]+)? URIHOST %{IPORHOST}(?::%{POSINT:port})? # uripath comes loosely from RFC1738, but mostly from what Firefox # doesn't turn into %XX URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*)+ #URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)? URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]* URIPATHPARAM %{URIPATH}(?:%{URIPARAM})? URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})? # Months: January, Feb, 3, 03, 12, December MONTH \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b MONTHNUM (?:0?[1-9]|1[0-2]) MONTHNUM2 (?:0[1-9]|1[0-2]) MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9]) # Days: Monday, Tue, Thu, etc... DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?) # Years? YEAR (?>\d\d){1,2} # Time: HH:MM:SS #TIME \d{2}:\d{2}(?::\d{2}(?:\.\d+)?)? # TIME %{POSINT<24}:%{POSINT<60}(?::%{POSINT<60}(?:\.%{POSINT})?)? HOUR (?:2[0123]|[01]?[0-9]) MINUTE (?:[0-5][0-9]) # '60' is a leap second in most time standards and thus is valid. SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?) TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9]) # datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it) DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR} DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR} DATESTAMP_US %{DATE_US}[- ]%{TIME} DATESTAMP_EU %{DATE_EU}[- ]%{TIME} ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE})) ISO8601_SECOND (?:%{SECOND}|60) TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}? TZ (?:[PMCE][SD]T|UTC) DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ} DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE} DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR} DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND} CISCOTIMESTAMP %{MONTH} %{MONTHDAY} %{TIME} # Syslog Dates: Month Day HH:MM:SS SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME} PROG (?:[\w._/%-]+) SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])? SYSLOGHOST %{IPORHOST} SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}> HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT} # Shortcuts QS %{QUOTEDSTRING:UNWANTED} # Log formats SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}: MESSAGESLOG %{SYSLOGBASE} %{DATA} COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{Bytes:bytes=%{NUMBER}|-}) COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent} COMMONAPACHELOG_DATATYPED %{IPORHOST:clientip} %{USER:ident;boolean} %{USER:auth} \[%{HTTPDATE:timestamp;date;dd/MMM/yyyy:HH:mm:ss Z}\] "(?:%{WORD:verb;string} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion;float})?|%{DATA:rawrequest})" %{NUMBER:response;int} (?:%{NUMBER:bytes;long}|-) # Log Levels LOGLEVEL ([A|a]lert|ALERT|[T|t]race|TRACE|[D|d]ebug|DEBUG|[N|n]otice|NOTICE|[I|i]nfo|INFO|[W|w]arn?(?:ing)?|WARN?(?:ING)?|[E|e]rr?(?:or)?|ERR?(?:OR)?|[C|c]rit?(?:ical)?|CRIT?(?:ICAL)?|[F|f]atal|FATAL|[S|s]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

XML カスタム分類子の書き込み

XML (Extensible Markup Language) は、ファイル内のタグを使用してドキュメントの構造を定義します。XML カスタム分類子で、行の定義に使用されるタグ名を指定できます。

AWS Glue のカスタム分類子の値

XML 分類子を定義する場合、AWS Glue に以下の値を指定し分類子を作成します。この分類子の分類フィールドは xml に設定してあります。

名前

分類子の名前。

行タグ

XML ドキュメントでテーブル行を定義する XML タグ名、山括弧 < > なし。名前は XML タグ規則に沿って命名する必要があります。

注記

行データを含む要素は、自動で閉じる空の要素にすることはできません。たとえば、次の空の要素は AWS Glue によって解析されません

<row att1=”xx” att2=”yy” />

空の要素は次のように記述できます。

<row att1=”xx” att2=”yy”> </row>

AWS Glue は、作成日時、最終更新時間、分類子のバージョンを追跡します。

たとえば、次の XML ファイルがあるとします。筆者と役職の列のみを含む AWS Glue テーブルを作成するには、行タグとして を使用し、 コンソールで分類子を作成します。次に、このカスタム分類子を使用するクローラを追加して実行します。

<?xml version="1.0"?> <catalog> <book id="bk101"> <AnyCompany> <author>Rivera, Martha</author> <title>AnyCompany Developer Guide</title> </AnyCompany> </book> <book id="bk102"> <AnyCompany> <author>Stiles, John</author> <title>Style Guide for AnyCompany</title> </AnyCompany> </book> </catalog>

JSON カスタム分類子の書き込み

JSON (JavaScript Object Notation) はデータ交換形式です。名前と値のペア、または順序付きの値のリストでデータ構造を定義します。JSON カスタム分類子では、データ構造への JSON パスを指定し、それを使用してテーブルのスキーマを定義できます。

AWS Glue のカスタム分類子の値

JSON 分類子を定義する場合、AWS Glue に以下の値を指定し分類子を作成します。この分類子の分類フィールドは json に設定してあります。

名前

分類子の名前。

JSON パス

テーブルスキーマを定義するために使用されるオブジェクトを指す JSON パス。JSON パスは、ドット表記またはブラケット表記で記述できます。以下の演算子がサポートされています。

演算子 説明
$ JSON オブジェクトのルート要素。すべてのパス式はこれで始まります
* ワイルドカード文字。JSON パスで名前または数値が必要な箇所でいつでも使用可能。
.<name> ドット表記の子。JSON オブジェクトの子フィールドを指定します。
['<name>'] ブラケット表記の子。JSON オブジェクトの子フィールドを指定します。1 つの子フィールドのみを指定できます。
[<number>] 配列インデックス。インデックスにより配列の値を指定します。

AWS Glue は、作成日時、最終更新時間、分類子のバージョンを追跡します。

例 JSON 分類子を使用して配列からレコードをプルする

JSON データがレコードの配列だとします。たとえば、ファイルの最初の数行は次のようになります。

[ { "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:1", "name": "Alabama's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:2", "name": "Alabama's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:3", "name": "Alabama's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:4", "name": "Alabama's 4th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:5", "name": "Alabama's 5th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:6", "name": "Alabama's 6th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:al\/cd:7", "name": "Alabama's 7th congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:1", "name": "Arkansas's 1st congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:2", "name": "Arkansas's 2nd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:3", "name": "Arkansas's 3rd congressional district" }, { "type": "constituency", "id": "ocd-division\/country:us\/state:ar\/cd:4", "name": "Arkansas's 4th congressional district" } ]

組み込み JSON 分類子を使用してクローラを実行する場合、ファイル全体がスキーマを定義するために使用されます。JSON パスを指定しないので、クローラはデータを 1 つのオブジェクト、つまり、ただの配列として処理します。たとえば、スキーマは次のようになります。

root |-- record: array

ただし、JSON 配列の各レコードに基づいたスキーマを作成するには、カスタム JSON 分類子を作成し、JSON パスを $[*] として指定します。この JSON パスを指定すると、分類子は配列内の 12 レコードすべてに問合せてスキーマを決定します。結果のスキーマには、各オブジェクトに次の例と同様の個別のフィールドが含まれています。

root |-- type: string |-- id: string |-- name: string

例 JSON 分類子を使用してファイルの一部のみを確認する

JSON データが、http://everypolitician.org/ から取られた JSON ファイルの例 s3://awsglue-datasets/examples/us-legislators/all/areas.json のパターンと同様だとします。JSON ファイルのサンプルオブジェクトは、次のようになります。

{ "type": "constituency", "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" } { "type": "constituency", "identifiers": [ { "scheme": "dmoz", "identifier": "Regional\/North_America\/United_States\/Alaska\/" }, { "scheme": "freebase", "identifier": "\/m\/0hjy" }, { "scheme": "fips", "identifier": "US02" }, { "scheme": "quora", "identifier": "Alaska-state" }, { "scheme": "britannica", "identifier": "place\/Alaska" }, { "scheme": "wikidata", "identifier": "Q797" } ], "other_names": [ { "lang": "en", "note": "multilingual", "name": "Alaska" }, { "lang": "fr", "note": "multilingual", "name": "Alaska" }, { "lang": "nov", "note": "multilingual", "name": "Alaska" } ], "id": "ocd-division\/country:us\/state:ak", "name": "Alaska" }

組み込み JSON 分類子を使用してクローラを実行する場合、ファイル全体がスキーマを作成するために使用されます。最終的に次のようなスキーマになります。

root |-- type: string |-- id: string |-- name: string |-- identifiers: array | |-- element: struct | | |-- scheme: string | | |-- identifier: string |-- other_names: array | |-- element: struct | | |-- lang: string | | |-- note: string | | |-- name: string

ただし、「id」オブジェクトだけを使用してスキーマを作成するには、カスタム JSON 分類子を作成し、JSON パスを $.id と指定します。その後、スキーマは「id」フィールドのみに基づくものとなります。

root |-- record: string

このスキーマで抽出されたデータの最初の数行は次のようになります。

{"record": "ocd-division/country:us/state:ak"} {"record": "ocd-division/country:us/state:al/cd:1"} {"record": "ocd-division/country:us/state:al/cd:2"} {"record": "ocd-division/country:us/state:al/cd:3"} {"record": "ocd-division/country:us/state:al/cd:4"} {"record": "ocd-division/country:us/state:al/cd:5"} {"record": "ocd-division/country:us/state:al/cd:6"} {"record": "ocd-division/country:us/state:al/cd:7"} {"record": "ocd-division/country:us/state:ar/cd:1"} {"record": "ocd-division/country:us/state:ar/cd:2"} {"record": "ocd-division/country:us/state:ar/cd:3"} {"record": "ocd-division/country:us/state:ar/cd:4"} {"record": "ocd-division/country:us/state:as"} {"record": "ocd-division/country:us/state:az/cd:1"} {"record": "ocd-division/country:us/state:az/cd:2"} {"record": "ocd-division/country:us/state:az/cd:3"} {"record": "ocd-division/country:us/state:az/cd:4"} {"record": "ocd-division/country:us/state:az/cd:5"} {"record": "ocd-division/country:us/state:az/cd:6"} {"record": "ocd-division/country:us/state:az/cd:7"}

JSON ファイルの「identifier」のように、深くネストされたオブジェクトに基づいてスキーマを作成するには、カスタム JSON 分類子を作成して JSON パスを $.identifiers[*].identifier と指定します。スキーマは前の例と似ていますが、JSON ファイル内の別のオブジェクトに基づいています。

スキーマは次のようになります。

root |-- record: string

テーブルからのデータの最初の数行のリストには、スキーマが「identifier」オブジェクトのデータに基づくものであることが示されます。

{"record": "Regional/North_America/United_States/Alaska/"} {"record": "/m/0hjy"} {"record": "US02"} {"record": "5879092"} {"record": "4001016-8"} {"record": "destination/alaska"} {"record": "1116270"} {"record": "139487266"} {"record": "n79018447"} {"record": "01490999-8dec-4129-8254-eef6e80fadc3"} {"record": "Alaska-state"} {"record": "place/Alaska"} {"record": "Q797"} {"record": "Regional/North_America/United_States/Alabama/"} {"record": "/m/0gyh"} {"record": "US01"} {"record": "4829764"} {"record": "4084839-5"} {"record": "161950"} {"record": "131885589"}

JSON ファイルの「name」配列の「other_names」フィールドのように、別の深くネストされたオブジェクトに基づいてテーブルを作成するには、カスタム JSON 分類子を作成して JSON パスを $.other_names[*].name と指定します。スキーマは前の例と似ていますが、JSON ファイル内の別のオブジェクトに基づいています。スキーマは次のようになります。

root |-- record: string

テーブルからのデータの最初の数行のリストには、「name」配列内の「other_names」オブジェクトのデータに基づくものであることが示されます。

{"record": "Alaska"} {"record": "Alaska"} {"record": "Аляска"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "ألاسكا"} {"record": "ܐܠܐܣܟܐ"} {"record": "الاسكا"} {"record": "Alaska"} {"record": "Alyaska"} {"record": "Alaska"} {"record": "Alaska"} {"record": "Штат Аляска"} {"record": "Аляска"} {"record": "Alaska"} {"record": "আলাস্কা"}