

# さまざまなデータ形式のカスタム分類子の記述
<a name="custom-classifier"></a>

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

 AWS Glue コンソールを使用して分類子を作成する方法の詳細については、「[AWS Glue コンソールを使用した分類子の作成](console-classifiers.md)」を参照してください。

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

**Topics**
+ [Grok カスタム分類子の書き込み](#custom-classifier-grok)
+ [XML カスタム分類子の書き込み](#custom-classifier-xml)
+ [JSON カスタム分類子の書き込み](#custom-classifier-json)
+ [CSV カスタム分類子の書き込み](#custom-classifier-csv)

## Grok カスタム分類子の書き込み
<a name="custom-classifier-grok"></a>

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

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

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

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

```
%{PATTERN:field-name}
```

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

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

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

```
%{NUMBER:num:int}
```

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

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

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

### grok 分類子のカスタム値
<a name="classifier-values"></a>

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

**名前**  
分類子の名前。

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

**Grok パターン**  
データストアに適用される一連のパターンで、一致があるかどうかを決定します。これらのパターンは AWS Glue の[組み込みパターン](#classifier-builtin-patterns)と定義されたカスタムパターンによるものです。  
grok パターンのシンプルな例を次に示します。  

```
%{TIMESTAMP_ISO8601:timestamp} \[%{MESSAGEPREFIX:message_prefix}\] %{CRAWLERLOGLEVEL:loglevel} : %{GREEDYDATA:message}
```
データが `TIMESTAMP_ISO8601` と一致すると、スキーマの列 `timestamp` が作成されます。動作は、例にある他の名前付きパターンに似ています。

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

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

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

### 組み込みパターン
<a name="classifier-builtin-patterns"></a>

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

次のリストは、各パターンの行です。各行で、パターン名の後に定義があります。[正規表現 (regex)](http://en.wikipedia.org/wiki/Regular_expression) 構文は、パターンを定義するために使用されます。

```
#<noloc>&GLU;</noloc> 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 カスタム分類子の書き込み
<a name="custom-classifier-xml"></a>

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

### XML 分類子のカスタム分類子値
<a name="classifier-values-xml"></a>

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 テーブルを作成するには、`AnyCompany` として [**行タグ**] を使用し、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 カスタム分類子の書き込み
<a name="custom-classifier-json"></a>

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

### AWS Glue のカスタム分類子の値
<a name="classifier-values-json"></a>

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

**名前**  
分類子の名前。

**JSON パス**  
テーブルスキーマを定義するために使用されるオブジェクトを指す JSON パス。JSON パスは、ドット表記またはブラケット表記で記述できます。以下の演算子がサポートされています。      
[See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/glue/latest/dg/custom-classifier.html)

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

**Example 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
```

**Example JSON 分類子を使用してファイルの一部のみを確認する**  
JSON データが、[http://everypolitician.org/](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": "আলাস্কা"}
```

## CSV カスタム分類子の書き込み
<a name="custom-classifier-csv"></a>

 カスタム CSV 分類子を使用すると、カスタム csv 分類子フィールドの各列のデータ型を指定できます。各列のデータ型をコンマで区切って指定できます。データ型を指定することで、クローラーが推測したデータ型を上書きし、データが適切に分類されるようにすることができます。

分類子で CSV を処理するための SerDe を設定でき、データカタログに適用されます。

カスタム分類子を作成すると、その分類子を別のクローラーで再利用することもできます。
+  ヘッダーのみ (データなし) の csv ファイルの場合、十分な情報が提供されないため、これらのファイルは UNKNOWN に分類されます。[Column headings] (列見出し) オプションで CSV の[Has headings](見出しあり) を指定し、データ型を指定すると、これらのファイルを正しく分類できます。

カスタム CSV 分類子を使用して、さまざまな種類の CSV データのスキーマを推測できます。分類子に指定できるカスタム属性には、区切り記号、CSV SerDe オプション、ヘッダーに関するオプション、およびデータに対して特定の検証を実行するかどうかなどがあります。

### AWS Glue のカスタム分類子の値
<a name="classifier-values-csv"></a>

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

**分類子名**  
分類子の名前。

**CSV Serde**  
分類子で CSV を処理するため、データカタログに適用される SerDe を設定します。オプションは、「Open CSV SerDe」、「Lazy Simple SerDe」、および「None」です。クローラーが検出を行う場合は、None 値を指定できます。

**列の区切り文字**  
行内の各列エントリを区切るものを示すカスタム記号。ユニコード文字を入力します。区切り記号を入力できない場合は、コピーと貼り付けをすることができます。これは、システムでサポートされていない文字 (通常は □ と表示) も含め、印刷可能な文字にも有効です。

**引用記号**  
コンテンツを単一の列の値に結合するものを示すカスタム記号。列の区切り文字とは異なる必要があります。ユニコード文字を入力します。区切り記号を入力できない場合は、コピーと貼り付けをすることができます。これは、システムでサポートされていない文字 (通常は □ と表示) も含め、印刷可能な文字にも有効です。

**列見出し**  
CSV ファイルで列見出しを検出する方法の動作を示します。カスタム CSV ファイルに列見出しがある場合は、列見出しのカンマ区切りリストを入力します。

**処理オプション: 単一列のファイルを許可します**  
1 つの列のみを含むファイルの処理を有効にします。

**処理オプション: 列値を識別する前に空白を削除します**  
列の値の型を識別する前に値をトリミングするかどうかを指定します。

**カスタムデータ型 – オプション**  
 カスタムデータ型をコンマで区切って入力します。CSV ファイル内のカスタムデータ型を指定します。カスタムデータ型は、サポートされているデータ型である必要があります。サポートされているデータ型は、「BINARY」、「BOOLEAN」、「DATE」、「DECIMAL」、「DOUBLE」、「FLOAT」、「INT」、「LONG」、「SHORT」、「STRING」、「TIMESTAMP」です。サポートされていないデータ型の場合、エラーが表示されます。